<?php
declare(strict_types=1);

namespace Service\OrderService;

use App\Model\BbcLogModel\OrderLog;
use App\Model\BbcModel\ChannelWx;
use App\Model\BbcModel\ConfigChannel;
use App\Model\BbcModel\GoodsPointsConfig;
use App\Model\BbcModel\MnBudget;
use App\Model\BbcModel\OrderReturn;
use App\Model\BbcModel\OrderReturnExtends;
use App\Model\BbcModel\SelfBuyCommission;
use App\Model\BbcModel\ShoppingGuide;
use App\Model\BbcModel\Storage;
use App\Model\BbcModel\StoreCard;
use App\Model\BbcModel\StoreCardLog;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use PHPUnit\Runner\Exception;
use Service\ActivityService\ActivityStoreService;
use Service\BaseService;
use Service\CouponService\CouponService;
use Service\GoodsService\CashGoodsService;
use Service\UserService\MnUserService;
use App\Model\BbcModel\Order;
use App\Model\BbcModel\OrderExtends;
use Service\UserService\CashManagerService;
use Service\StoreCardService\StoreCardService;
use Service\GoodsService\ChannelGoodsService;
use Service\Code\Normal;
use Service\OrderService\Volidate\CashOrderVolidate;
use Service\Code\CodeBuilder;
use Service\StorageService\StorageService;
use Service\ChannelService\ChannelWxService;
use Service\ConfigureService\ChannelConfigService;
use Service\ChannelService\StoreConfigService;
use App\Model\BbcModel\Member;
use App\Model\BbcModel\PointsLog;
use Service\PointsService\PointsService;
use Service\MemberService\MemberService;
use App\Model\BbcModel\MnStoreGoods;
use App\Model\BbcModel\GoodsBatch;
use App\Model\BbcModel\StockLog;
use App\Model\BbcModel\OrderGoods;
use App\Model\BbcModel\MnCommission;
use App\Model\BbcModel\Mnuser;
use App\Model\BbcModel\OrderReportStatus;
use Service\MessageService\SmsService;
use Service\DeclareService\WayBillDeclareService;
use Service\PayService\CashPayService;
use Service\PushService\PushYunCangApiService;
use Service\AreaService\AreaService;
use App\Model\BbcModel\Address;
use App\Model\BbcModel\MemberInfo;
use App\Model\BbcModel\GoodsSale;
use App\Model\BbcModel\Goods;
use Service\DeclareService\PayDeclareService;
use App\Model\BbcModel\PushAgain;
use Service\HelperService\StringService;
use Service\DeclareService\ReportLogService;
use App\Model\BbcModel\OrderReportLog;
use Service\HanshowService\HanshowService;
use Service\GoodsPointsService\GoodsPointsService;
use App\Model\BbcModel\CouponUser;
use App\Model\BbcModel\CouponManual;
use App\Model\BbcModel\CashRegister;
use App\Model\BbcModel\YunCangSupplier;
use function PHPStan\dumpType;

/**
 * 收银机订单中心
 * @author chenshubo
 */
class CashOrderService extends BaseService
{
    /**
     * 创建订单接口
     * @param int $cid 渠道ID
     * @param int $mn_sid 店铺ID
     * @param int $manager_id 收银员ID
     * @param int $cash_register_id 收银台
     * @param string $client 终端 
     * @param array $body 创建订单所需要的参数
     * @return mixed
     */
    public function placeOrder
    (
        int $cid,
        int $mn_sid,
        int $manager_id,
        int $cash_register_id,
        string $client,
        array $body = []
    )
    {

        $time = !empty($body['time']) ?$body['time']: time();
        $order_type = 3;
        if( isset($body['order_type']) && $body['order_type'] == 4 ) {
            $order_type = 4;
        }

        $body['order_type'] = $order_type;

        //校验下单参数
        $body['mn_sid'] = $mn_sid;
        $body['cid']    = $cid;
        $body['mid']    = (int)($body['mid'] ?? 0);
        $result_order_check = CashOrderVolidate::instance()->checkOrderData($cid,$mn_sid,$body);
        if( $result_order_check['code'] != Normal::SUC ) {
            return $result_order_check;
        }
        $cash_register= CashRegister::instance()->info(['id'=>$cash_register_id]);
        if(empty($cash_register)){
            return Normal::returnCode(Normal::FAIL,"未找到收银台");
        }
        //得到最终下单计算之后的价格及参数
        $body       = $result_order_check['data'];
        $mid        = (int)($body['mid'] ?? 0);
        $mn_user    = $body['mn_user'];
//        $order_sn   = !empty($body['sn'])?$body['sn']:$this->getBuilderSn($mn_sid);

        //线下仓库
        $storage = StorageService::instance()->queryStorage($mn_sid,0);
        if( empty($storage) ) {
            return Normal::returnCode(Normal::FAIL,"仓库信息未找到，请联系管理员或者登录店铺后台进行确认!");
        }

        //微信小程序配置
        $channelWxConfig = ChannelWxService::instance()->queryWxConfig($cid);
        if( empty($channelWxConfig) ) {
            return Normal::returnCode(Normal::FAIL,"微信小程序相关配置未找到，请联系管理员或者登录店铺后台进行确认!");
        }

        //获取店铺利润是否包含积分支付金额 ,1-包含
        $storeProfitType = GoodsPointsService::instance()->storeProfitType($cid);

        $orderGroupData = $this->orderGroup($body['goods']);

        $scan_rece = $body['scan_rece'] ?? 0;
        $scan_code = $body['scan_code'] ?? 0;
        Order::instance()->startTrans();
        try {


            //写订单数据
            $createOrderResult = $this->createOrder($cid,$body,$orderGroupData,$mn_sid,$mid,$client,$cash_register_id,$manager_id,$time,$storeProfitType);

            /*\Hyperf\Utils\ApplicationContext::getContainer()
                ->get(LoggerFactory::class)
                ->get('$createOrderResult','info')
                ->info(json_encode($createOrderResult));*/

            if($createOrderResult['code'] != Normal::SUC){
                throw new Exception($createOrderResult['msg']);
            }
            $createOrderResultData = $createOrderResult['data'];
            $pay_sn = $createOrderResultData['pay_sn'];


            //储值卡消费
            $storecard_id = $body['storecard_id'] ?? 0;
            $store_card_money = $body['storecard'] ?? 0;
            if( $storecard_id > 0 ) {
                $result_user_storecard = StoreCardService::instance()->userStoreCardConsumer($storecard_id,$store_card_money,[
                    'order_sn'  => $pay_sn,
                    'cid'       => $cid,
                    'mn_sid'    => $mn_sid
                ]);
                if( $result_user_storecard['code'] != Normal::SUC ) {
                    throw new Exception($result_user_storecard['msg']);
                }
            }

            //更新优惠状态
            $coupon_id = $body['coupon_id'] ?? 0;
            if($coupon_id > 0 ){
                $coupon = CouponUser::instance()->info(['mid'=>$mid,'mn_sid'=>$mn_sid,'coupon_id'=>$coupon_id,'status'=>1]);
                if($coupon){
                    CouponUser::instance()->edit(['id'=>$coupon['id']],['sn'=>$pay_sn,'use_time'=>$time,'status'=>2]);
                    if($coupon['manual_id']>0){
                        CouponManual::instance()->edit(['id'=>$coupon['manual_id']],['status'=>3,'use_time'=>$time]);
                    }
                }else{
                    throw new Exception('该优惠券已使用或过期');
                }
            }

            //更新会员累计消费
            if( $mid > 0 ) {
                $result_member_consume = MemberService::instance()->memberOrderMoneyConsume($mid,(string)$body['price_order'],(int)$time);
                if( $result_member_consume['code'] != Normal::SUC ) {
                    throw new Exception($result_member_consume['msg']);
                }
            }

            if( $scan_rece > 0)
            {
                $extra = [
                    'auth_code'         => str_replace(["\r\n","\r","\n"," "], "", $scan_code),
                    'out_trade_no'      => $pay_sn,
                    'body'              => '门店付款',
                    'total_fee'         => $scan_rece,
                    'cid'               => $cid,
                    'mn_sid'            => $mn_sid,
                    'store_type'        => $mn_user['type'],
                    'buyer'             => $body['buyer'],
                    'order_id'          => $pay_sn,
                    'scan_rece_type'    => $createOrderResultData['scan_rece_type'],
                    'is_order'          => 1,
                    'cash_register'     => $cash_register
                ];

                //调用收银机支付服务中心
                $user_pay_result = CashPayService::instance()->userPay($cid, $mn_sid,4, $extra);
                if( $user_pay_result['code'] != Normal::SUC ) {
                    throw new Exception($user_pay_result['msg']);
                }

            }
            Order::instance()->commit();
        }catch ( \Exception  $e){
            Order::instance()->rollback();
            return Normal::returnCode(Normal::FAIL,$e->getMessage());
        }

        if( $scan_rece > 0)
        {
            $order_id = Order::instance()
                ->where(['pay_sn' => $pay_sn])
                ->pluck('id')->toArray();
            $createOrderResult = Order::instance()
                ->whereIn('id',$order_id)
                ->update([
                      'pay_serial'     => $user_pay_result['data']['transaction_id'],
                      'initalRequest'  => $user_pay_result['data']['initalRequest'],
                      'initalResponse' => $user_pay_result['data']['initalResponse'],
                      'pay_time'       => $user_pay_result['data']['pay_time'] ?? time()
                ]);
            if(!$createOrderResult)
            {
                return Normal::returnCode(Normal::FAIL,'订单表更新失败');
            }
            $OrderExtendsResult = OrderExtends::instance()
                ->whereIn('order_id',$order_id)
                ->update([
                     'scan_sn' => $user_pay_result['data']['transaction_id'],
                     'user_pay_type' => $user_pay_result['data']['auth_user_pay_type']
                ]);
            if(!$OrderExtendsResult)
            {
                return Normal::returnCode(Normal::FAIL,'订单扩展表更新失败');
            }
            //运单申报和运单订单推送
            if($createOrderResultData['pushYunCangOrderData'])
            {
                $this->CashOrderVolidate($cid,$mn_sid,$createOrderResultData['pushYunCangOrderData'],$user_pay_result['data']);
            }

            //自建商品不需要申报
            if(isset($user_pay_result['data']['payreport_data']) && $user_pay_result['data']['payreport_data'])
            {
                //支付单申报
                $uri          = request()->getUri();
                $callback_url = $uri->getScheme() . '://' . $uri->getHost();
                $uriport      = $uri->getPort();
                if (!empty($uriport) && !in_array((string)$uriport, ['80', '443'])) {
                    $callback_url = $callback_url . ':' . $uriport;
                }
                $payreport_data           = $user_pay_result['data']['payreport_data'];
                $payreport_data['domain'] = $callback_url;
                \Hyperf\Utils\ApplicationContext::getContainer()
                    ->get(LoggerFactory::class)
                    ->get('$payreport_data','info')
                    ->info(json_encode($payreport_data));
                PayDeclareService::instance()->publishMsg($payreport_data);
            }
        }

        //电子价签
        $hanshow_config = StoreConfigService::instance()->getConfig('hanshow_config', $mn_sid);
        $hanshow_show   = $hanshow_config['show'] ?? 0;
        if($hanshow_show==1){
            $hanshow_data = [
                'config'   => $hanshow_config,
                'goodsIds' => array_column($body['goods'], 'goods_id'),
                'mn_sid'   => $mn_sid
            ];
            HanshowService::instance()->publishMsg($hanshow_data);
        }

        $points = isset($body['points']) ? $body['points'] : 0;
        //有积分的情况下，下单成功需要发短信通知客户
        if( $points > 0 )
        {
            $memberinfo = MemberService::instance()->getMemberByMid($mid);
            $message = [
                'cid'       => $cid,
                'mid'       => $mid,
                'mobile'    => $memberinfo['account'],
                'code'      => "您的{$memberinfo['account']}账户在{$mn_user['store_name']}支出{$points}积分,当前剩余{$memberinfo['points']}积分",
                'temp'      => 'customize'
            ];
            SmsService::instance()->publishMsg($message);
        }

        return Normal::returnCode(
            Normal::SUC,
            '操作成功',
            ['sn' => $pay_sn,'is_combination_order' => $createOrderResultData['is_combination_order']],
        );
    }
    
    /**
     * 推送云仓订单数据
     * @param int $cid
     * @param int $mn_sid
     * @param array $extra
     */
    public function pushYunCangOrder(int $cid,int $mn_sid,array $extra)
    {
        $scan_rece_type = $extra['scan_rece_type'];
        $order_sn       = $extra['order_sn'];
        $time           = $extra['time'];
        $order_id       = $extra['order_id'];
        $mid            = $extra['mid'];
        $user_pay_result= $extra['user_pay_result'];
        
        //向云仓推送订单
        $companyconfig  = StoreConfigService::instance()->getConfig('e_company',$mn_sid);
        
        //获取支付方式
        $payway         = CashPayService::instance()->pay_way[$scan_rece_type];
        $orderPayData   = [
            'cid'               =>  $cid,
            'payTime'           =>  $time,
            'enterpriseNum'     =>  $companyconfig['eCompanyCode']??'',
            'enterpriseName'    =>  $companyconfig['eCompanyName']??'',
        ];
        
        if( $payway == 'hnapay' )
        {
            $hnapayconfig                   = StoreConfigService::instance()->getConfig('hnapay_pay',$mn_sid);
            $hnapayconfigdata               = $hnapayconfig;
            $orderPayData['payWay']         = 4;
            $orderPayData['payCommanyName'] = $hnapayconfigdata['payCommanyName']??'';
            $orderPayData['payCommanyCode'] = $hnapayconfigdata['payCommanyCode']??'';
        }
        elseif( $payway == 'allinpay' )
        {
            $allinpay_payconfig             = StoreConfigService::instance()->getConfig('allinpay_pay',$mn_sid);
            $allinpayconfigdata             = $allinpay_payconfig;
            $orderPayData['payWay']         = 0;
            $orderPayData['payCommanyName'] = $allinpayconfigdata['payCommanyName']??'';
            $orderPayData['payCommanyCode'] = $allinpayconfigdata['payCommanyCode']??'';
        }
        elseif( $payway == 'alipay' )
        {
            $orderPayData['payWay']             = 6;
            $orderPayData['payCommanyName']     = '支付宝(中国)网络技术有限公司';
            $orderPayData['payCommanyCode']     = '31222699S7';
        }
        elseif( $payway == 'helipay' )
        {
            $orderPayData['payWay']             = 0;
            $orderPayData['payCommanyName']     = '广州合利宝支付科技有限公司';
            $orderPayData['payCommanyCode']     = '44309655JY';
        }
        else
        {
            $orderPayData['payWay']             = 5;
            $orderPayData['payCommanyName']     = '财付通支付科技有限公司';
            $orderPayData['payCommanyCode']     = '4403169D3W';
        }
        
        //运单申报结果
        $logisticReport = $extra['logisticReport'];
        
        $orderPayData["payDecarleResponse"]     = $user_pay_result['initalResponse'] ?? '';
        $orderPayData["payDecarleRequest"]      = $user_pay_result['initalRequest'] ?? '';
        $orderPayData["orderSn"]                = $order_sn;
        $orderPayData["paySerial"]              = $user_pay_result['transaction_id'] ?? '';
        $orderPayData["logisticNo"]             = $logisticReport['data']['waybillNo'] ??'';
        $orderPayData["logisticCode"]           = $logisticReport['data']['logisticCustomCode']??"";
        $orderPayData["logisticName"]           = $logisticReport['data']['logisticCustomName']??'';
        $orderPayData["logisticWayBillContent"] = $logisticReport['data']['originData']??'';
        
        //订单创建数据
        $orderCreateData = $extra['orderCreate'];
        //直接写入重推队列，
        $push = [];
        $push['sync_data']  = json_encode($orderCreateData, JSON_UNESCAPED_UNICODE);
        $push['code']       = 0;
        $push['msg']        = '待推送';
        $push['pay_data']   = json_encode($orderPayData, JSON_UNESCAPED_UNICODE);
        $push['order_id']   = $order_id;
        PushAgain::instance()->add($push);
        return Normal::returnCode(Normal::SUC,'执行成功');
        /*
        //预警配置
        $monitor_config = ChannelConfigService::instance()->getChannelConfig('monitor_mobile',$cid);
        $mobile = $monitor_config['mobile']??'';
        
        //运单申报失败，发送监控短信
        if( $logisticReport['code'] != Normal::SUC ) 
        {
            if($mobile){
                $message = [
                    'cid'       => $cid,
                    'mid'       => $mid,
                    'mobile'    => $mobile,
                    'code'      => "运单申报失败,订单号[{$order_sn}],失败原因[{$logisticReport['msg']}]",
                    'temp'      => 'failorder'
                ];
                SmsService::instance()->publishMsg($message);
            }
            //写入重新推送队列
            $push = [];
            $push['sync_data']  = json_encode($orderCreateData, JSON_UNESCAPED_UNICODE);
            $push['code']       = 0;
            $push['msg']        = '运单申报失败';
            $push['pay_data']   = json_encode($orderPayData, JSON_UNESCAPED_UNICODE);
            $push['order_id']   = $order_id;
            PushAgain::instance()->add($push);
        }
        else
        {
            $push_order_create_result = PushYunCangApiService::instance()->push($cid,'createOrder',$orderCreateData);
            if( $push_order_create_result['code'] != Normal::SUC )
            {
                $push = [];
                $push['sync_data']  = json_encode($orderCreateData, JSON_UNESCAPED_UNICODE);
                $push['code']       = $push_order_create_result['code'];
                $push['msg']        = $push_order_create_result['msg'];
                $push['pay_data']   = json_encode($orderPayData, JSON_UNESCAPED_UNICODE);
                $msg = $push_order_create_result['msg'] ?? '请求失败';
                if($mobile){
                    $message = [
                        'cid'       => $cid,
                        'mid'       => $mid,
                        'mobile'    => $mobile,
                        'code'      => "推送云仓订单创建失败,订单号[{$order_sn}],失败原因[{$msg}]",
                        'temp'      => 'failorder'
                    ];
                    SmsService::instance()->publishMsg($message);
                }
                $push['order_id'] = $order_id;
                PushAgain::instance()->add($push);
            } 
            else
            {
                $returnData = $push_order_create_result['data']['orderItems'];
                $return_sn = [];
                foreach ($returnData as $v) {
                    $skuCodes = array_column($v['goods_items'], 'goodsSku');
                    foreach ($skuCodes as $value) {
                        $return_sn[$value] = $v['orderNo'];
                    }
                }
                
                Order::instance()->edit(['id'=>$order_id], ['push_success'=>1]);
                $editgoods= OrderGoods::instance()->lists(['order_id'=>$order_id]);
                foreach ($editgoods as $k => $v) 
                {
                    $stb_sn = $return_sn[$extra['goodsListMap'][$v['goods_id']]['skucode']];
                    OrderGoods::instance()->edit(['id'=>$v['id']], ['stb_sn'=>$stb_sn]);
                }
                $pushPayResult = PushYunCangApiService::instance()->push($cid,'OrderPay',$orderPayData);
                if( $pushPayResult['code'] == Normal::SUC )
                {
                    Order::instance()->edit(['id'=>$order_id], ['pay_success'=>1]);
                }
                else
                {
                    $msg = $pushPayResult['msg'] ?? '请求失败';
                    if($mobile){
                        $message = [
                            'cid'       => $cid,
                            'mid'       => $mid,
                            'mobile'    => $mobile,
                            'code'      => "推送云仓订单支付回传失败,订单号[{$order_sn}],失败原因[{$msg}]",
                            'temp'      => 'failorder'
                        ];
                        SmsService::instance()->publishMsg($message);
                    }
                    $payAgain= PushAgain::instance()->info(['order_id'=>$order_id]);
                    if($payAgain)
                    {
                        PushAgain::instance()->edit(['id'=>$payAgain['id']],['pay_data'=>json_encode($orderPayData, JSON_UNESCAPED_UNICODE)]);
                    }
                    else
                    {
                        PushAgain::instance()->add([
                            'pay_data'  => json_encode($orderPayData, JSON_UNESCAPED_UNICODE),
                            'order_id'  => $order_id,
                            'cd'        => time(),
                            'msg'       => $pushPayResult['msg']
                        ]);
                    }
                }
            }
        }*/
    }
    
    /**
     * 处理订单商品
     * @param array $order_goods
     * @param array $extra
     * @return mixed
     */
    public function dealOrderGoods(array $order_goods, array $extra = [],$storeProfitType = 1,$orderAddData)
    {

        $orderGoodsInsertData = $yunCangOrderGoods = $mnCommissionData = [];
        
        //店铺商品数据获取
        $cid                    = $extra['cid'];
        $mn_sid                 = $extra['mn_sid'];
        $mnGoodsListMap         = $extra['mnGoodsListMap'];
        $mnGoodsBatchListMap    = $extra['mnGoodsBatchListMap'];
        $goodsListMap           = $extra['goodsListMap'];
        $commissionflag         = $extra['commissionflag'];        
        $pay_percent            = $extra['pay_percent'];
        $pay_fee                = $extra['pay_fee'];
        $surplusonlinepay       = $extra['surplusonlinepay'];
        $mn_user                = $extra['mn_user'];
        $thaw_time                  = $extra['time'];//todo 配置天数
        $distribute_money           = '0.00';
        $order_profit               = '0.00';
        $push_order_goods_data      = [];
        $push_total_goods_money     = '0.00';
        $totalgoods                 = count($order_goods);
        $goodskeyflag               = $totalgoods-1;
        $total_commission           = round(bcmul((string)$surplusonlinepay,(string)$pay_fee,3),2);//总分佣
        $total_commission_s         = $total_commission;//总分佣剩余
        $yc_goods_price             = '0.00';
        $goodsCount                 = 0;
        $points_money               = 0;
        //处理下单商品
        foreach ($order_goods as $key => $goods) 
        {
            $goods_id       = (int)$goods['goods_id'];
            //获取商品信息
            $goodsinfo                  = $goodsListMap[$goods_id];

            //扣订单商品库存

            $batch_id       = (int)$goods['batch_id'];
            $goods_num      = (int)$goods['num'];
            $goods_name     = $goods['goods_name'];
            $price_pay      = (string)$goods['price_pay'];
            $price_cost     = (string)$goods['price_cost'];

            $stock_result   = $this->deductGoodsStock($cid,$mn_sid,$goods_id,$batch_id,$goods_num,$mnGoodsListMap,$mnGoodsBatchListMap,$extra);
            if( $stock_result['code'] != Normal::SUC ) {
                return Normal::returnCode(Normal::FAIL,"商品【{$goods_name}】{$stock_result['msg']}");
            }
            
            //获取批次信息
            $batch                      = current($mnGoodsBatchListMap[$goods_id]);

//            $goods_cost_total           = bcmul((string)$price_cost,(string)$goods_num, 3);


            if ($goods['is_combine_goods'] == 1) { //组合商品的店铺预估收益

                $combineGoodsTaxFeeRes = $this->combineGoodsTaxFee($extra['cid'], $goods,1);

                $goods['combine_goods_json_body'] = $combineGoodsTaxFeeRes['combine_goods_json_body'];

                $order_profit = $order_profit + ($price_pay - $combineGoodsTaxFeeRes['store_store_total_tax']) * $goods_num;
            }else{

                $single_price_pay = $price_pay;
                $tax_rate = $goods['tax_rate'];
                if($goods['high_price'] > 0 && $single_price_pay >= $goods['high_price']){
                    $tax_rate = $goods['high_tax_rate'];
                }

                $single_price_cost = $price_cost / $goods_num;
                $single_price_cost   = round($single_price_cost / (1 + $tax_rate),2) * $goods_num; //反算不含税的店铺成本价
                $goods_profit = ($price_pay - $single_price_cost) * $goods_num;
                $order_profit = round(($order_profit + $goods_profit), 2);
            }

            if($order_profit > 0 && $storeProfitType == 0 && $orderAddData['points_money'] > 0) //店铺利润不包含积分支付金额
            {
                if($goodsCount < count($order_goods))
                {
                    //积分抵扣金额
                    $goods_points_money = round($orderAddData['points_money'] * ($goods['price_total'] / $orderAddData['price_total']),2);

                    $order_profit = $order_profit - $goods_points_money;
                    $points_money += $goods_points_money;
                }
                else
                { //最后一次循环
                    $goods_points_money = $orderAddData['points_money'] - $points_money;
                    $order_profit = $order_profit - $goods_points_money;
                }
                if($order_profit < 0){
                    $order_profit = 0;
                }
            }
            $goodsCount++;

            $price_pay = $price_pay * $goods_num;
            $goods['price_pay'] = $price_pay;

            if( $commissionflag )
            {
                if( $goodskeyflag == $key ) {//如果是数组中最后一个商品,则使用已经分配剩下分佣金额
                    $goodscommission = $total_commission_s;
                } else {
                    $onlinepaygoods     = round(bcmul((string)$price_pay,(string)$pay_percent,3),2);//当前商品的在线支付金额
                    $goodscommission    = round(bcmul((string)$onlinepaygoods,(string)$pay_fee,3),2);//分佣金额为平摊的支付金额扣除千六
                    $total_commission_s = bcsub((string)$total_commission_s,(string)$goodscommission,2);//减去每次分佣金额
                }
                $goods_distribute_money = $goodscommission;
            }else{
                $goods_distribute_money = 0;
                $goodscommission        = 0;
            }

            unset($goods['batch_id']);
            $goods['price_fullReduction']   = $goods['price_fullReduction']??0;
            $goods['price_modifyDiscount']  = $goods['price_modifyDiscount']??0;
            $goods['price_vipDiscount']     = $goods['price_vipDiscount']??0;
            $goods['price_discount']        = $goods['price_discount']??0;
            $goods['activity_id']           = $goods['activity_id']??0;
            $goods['is_send']               = $goods['is_send']??0;
            $goods['order_id']              = $extra['order_id'];
            $goods['mn_sid']                = $mn_sid;
            $goods['spec_num']              = 1;
            $goods['mid']                   = $extra['mid'];
            $goods['mnid']                  = 4;
            $goods['batch_no']              = $batch['batch_no'];
            $goods['tax_rate']              = $goodsinfo['tax_rate'];
            $goods['distribute_money']      = $goods_distribute_money;
            $distribute_money           = bcadd((string)$distribute_money,(string)$goods['distribute_money'],2);
            $batchs                     = [['batch_id'=>$batch_id,'batch_no'=>$batch['batch_no'],'num'=>$goods_num]];
            $goods['batch_actual']      = json_encode($batchs,JSON_UNESCAPED_UNICODE);
            $goods['sid']               = $mn_user['sid'];
            $goods['price_tax']         = $goods['price_tax'] * $goods_num;

            //计算店铺成本的税率
            $tax_rate = $goods['tax_rate'];
            if($goods['high_price'] > 0 && $goods['price_cost'] >= $goods['high_price']){
                $tax_rate = $goods['high_tax_rate'];
            }
            $goods['store_rate']        = $tax_rate;

            unset($goods['high_price']);
            unset($goods['store_isCombineOrders']);
            unset($goods['supplier_id']);
            unset($goods['total_price_total']);
            unset($goods['total_price_pay']);
            unset($goods['total_price_cost']);
            unset($goods['total_channel_cost']);
            unset($goods['total_price_tax']);
            unset($goods['cost_rate']);
            unset($goods['high_tax_rate']);
            unset($goods['coupon_id']);
            unset($goods['price_goods_reduction']);
            unset($goods['is_trade']);


            $orderGoodsInsertData[] = $goods;

            //处理商品含税金额问题
            if(isset($goods['price_tax'])){
                $price  = bcdiv(bcadd((string)$price_pay,(string)$goods['price_tax'],3),(string)$goods_num,3);
            }else{
                $price  = bcdiv(bcadd((string)$price_pay,'0.00',3),(string)$goods_num,3);
            }
            $goodsPrice = ceil(round($price*100,1))/100;

            //组装云仓推送商品
            $yunCangOrderGoods[] = [
                'goodsSku'              => $goodsinfo['skucode'],
                'goodsNum'              => $goods_num,
                'goodsSpecNum'          => 1,
                'goodsBatchNo'          => '',
                'goodsTax'              => 0,
                'goodsPrice'            => $goodsPrice //优惠之前的销售价单价（含税价）
            ];

            $yc_goods_price = bcadd((string)$yc_goods_price, bcmul((string)$goodsPrice,(string)$goods_num,2),2);
            //店铺分佣数据
            $mnCommissionData[] = [
                'cd'            => $extra['time'],
                'mn_sid'        => $mn_sid,
                'from_mid'      => $extra['mid'],
                'to_mid'        => $mn_user['mid'],
                'order_price'   => $extra['price_order'],
                'mnid'          => 4,
                'sn'            => $extra['order_sn'],
                'order_type'    => 7,
                'money'         => $goodscommission,
                'goods_id'      => $goods_id,
                'status'        => 0,
                'thaw_time'     => $thaw_time,
                'sid'           => $mn_user['sid']
            ];
        }

        return Normal::returnCode(Normal::SUC,"获取成功",[
            'orderGoodsInsertData'  => $orderGoodsInsertData,
            'yunCangOrderGoods'     => $yunCangOrderGoods,
            'mnCommissionData'      => $mnCommissionData,
            'yc_goods_price'        => $yc_goods_price,
            'distribute_money'      => $distribute_money,
            'order_profit'          => $order_profit,
            'total_commission'      => $total_commission,
        ]);
    }
    
    /**
     * 订单扣减库存
     * @param int $cid
     * @param int $mn_sid
     * @param int $goods_id
     * @param int $batch_id
     * @param int $goods_num
     * @param array $mnGoodsListMap
     * @param array $mnGoodsListMap
     * @param array $extra
     * @return mixed
     */
    public function deductGoodsStock(int $cid,int $mn_sid,int $goods_id,int $batch_id,int $goods_num,array $mnGoodsListMap,array $mnGoodsBatchListMap,array $extra = [])
    {
        $mn_goods_data  = $mnGoodsListMap[$goods_id];
        $mn_goods_id    = $mn_goods_data['id'];
        $stock_share    = $extra['stock_share'];
        
        //线下库存
        $mnstoregoodsres= MnStoreGoods::instance()->where(['id'=>$mn_goods_id])->where('quantity','>=',$goods_num)->decrement('quantity',$goods_num);
        if(!$mnstoregoodsres){
            return Normal::returnCode(Normal::FAIL, '线下库存不足');
        }

        $goods_info = Goods::instance()->info(['id' => $goods_id]);
        if($goods_info['df'] == 1 && $goods_info['is_trade'] == 1)
        {
            $mn_store_goods = MnStoreGoods::instance()->where(['id'=>$mn_goods_id])->first();
            if($mn_store_goods['quantity'] <= 0)
            {
                MnStoreGoods::instance()->where(['id'=>$mn_goods_id])->update(['df' => 1,'status' => 0]);
            }
        }

        //线下商品线上可用库存
        if( $stock_share == 1 ) {
            $mnstoregoodsres2= MnStoreGoods::instance()->where(['id'=>$mn_goods_id])->decrement('num',$goods_num);
            if(!$mnstoregoodsres2){
                return Normal::returnCode(Normal::FAIL,'线下商品线上可用库存不足');
            }
        }
        //处理商品销量 increment
        MnStoreGoods::instance()->where(['id'=>$mn_goods_id])->increment('num_sale',$goods_num);
        Goods::instance()->where(['id'=>$goods_id])->increment('num_sale',$goods_num);
        Goods::instance()->where(['id'=>$goods_id])->increment('fictitious_sale',$goods_num);
        Goods::instance()->edit(['id'=>$goods_id],['sale_time'=>time()]);
        $goodsSaleListMap=$extra['goodsSaleListMap'];
        if(isset($goodsSaleListMap[$goods_id])){
            GoodsSale::instance()->where(['id'=>$goodsSaleListMap[$goods_id]['id']])->increment('num_sale',$goods_num);
        }else{
            GoodsSale::instance()->add(['goods_id'=>$goods_id,'cid'=>$cid,'num_sale'=>$goods_num]);
        }
        
        //商品批次
        $goodsBatch = $mnGoodsBatchListMap[$goods_id];
        if( empty($goodsBatch) ) {
            return Normal::returnCode(Normal::FAIL, '未找到相关批次库存信息');
        }
        
        $batchsdata = [];
        $nowquantity = $goods_num;
        foreach ($goodsBatch as $batch) 
        {
            $batchid        = $batch['id'];
            $batch_stock    = $batch['num'];
            $batch_no       = $batch['batch_no'];
            
            //如果当前批次不够，则减去库存之后，继续扣除另一个批次的库存
            if( $nowquantity >= $batch_stock ) {
                $batchres = GoodsBatch::instance()->where(['id'=>$batchid])->decrement('num',$batch_stock);
                $num    = $batch_stock;
                $batchsdata[]=['batch_id'=>$batchid,'num'=>$batch_stock,'batch_no'=>$batch_no];
            } else {
                $batchres = Goodsbatch::instance()->where(['id'=>$batchid])->decrement('num',$nowquantity);
                $num    = $nowquantity;
                $batchsdata[]=['batch_id'=>$batchid,'num'=>$nowquantity,'batch_no'=>$batch_no];
            }
            
            $nowquantity= bcsub((string)$nowquantity,(string)$num);
            if(!$batchres){
                return Normal::returnCode(Normal::FAIL,'批次库存扣减失败');
            }
            $stockLog = [
                'manager_id'        => $extra['manager_id'] ??0,
                'cid'               => $cid,
                'mn_sid'            => $mn_sid,
                'mnstoregoods_id'   => $mn_goods_id,
                'goods_id'          => $goods_id,
                'batch_id'          => $batchid,
                'quantity'          => $num,
                'type'              => 3,
                'bill_id'           => $extra['order_id'],
                'bill_code'         => $extra['order_sn'],
                'status'            => 0,
                'remarks'           => '门店销售',
                'cd'                => $extra['time']??time()
            ];
            StockLog::instance()->add($stockLog); 
            if($nowquantity==0){
                break;
            }
        }
        
        if( $nowquantity > 0 ) {
            return Normal::returnCode(Normal::FAIL,'批次库存不足扣减');
        }
        return Normal::returnCode(Normal::SUC, '成功',$batchsdata);
    }
    
    /**
     * 获取收银机订单列表
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     */
    public function orderList(int $cid,int $mn_sid,array $body = [])
    {
        $page   = $body['page']??1;
        $limit  = $body['limit']??10;
        $mn_user= MnUserService::getMnUserInfoByMnSid((int)$mn_sid);
        $table = Order::instance()->getTable();
        $query = Order::instance()
        ->from("{$table} as o")
        ->leftJoin('ly_member as m','o.mid','=','m.mid')
        ->leftJoin('ly_member_info as mi','o.mid','=','mi.mid')
        ->leftJoin('ly_order_report_status as ors','o.id','=','ors.order_id')
        ->leftJoin('ly_order_extends as  oes','o.id','=','oes.order_id')
        ->where('o.df',0)
        ->where('o.mn_sid',$mn_sid)
        ->whereIn('o.type',[3,4]);
        
        /*if( $mn_user['type'] == 3 ){
            $query->where('o.type',4);
        }else{
            $query->where('o.type',3);
        }*/
        if ( isset($body['search']) && !empty($body['search']) ) {
            $search = $body['search'];
            $query->where(function($query) use ($search)
            {
                $query->where('o.sn','like',"%{$search}%")
                ->orWhere('m.account','like',"%{$search}%")
                ->orWhere('o.buyer_mobile','like',"%{$search}%");
            });
        }
        if (!empty($body['starttime'])) {
            $query->where('o.cd','>=',strtotime($body['starttime']));
        }
        
        if (!empty($body['endtime'])) {
            $query->where('o.cd','<=',strtotime($body['endtime']));
        }
        
        if (isset($body['clear_status']) && $body['clear_status'] !='') {
            $query->where('o.status','>=',20);
            $clear_status = $body['clear_status'];
            if($body['clear_status']==2){
                $query->where(function($query) use ($clear_status){
                   $query->orWhere('ors.clear_status','=',2)
                    ->orWhere('ors.express_status','=',2)
                    ->orWhere('ors.express_status','=',2)
                    ->orWhere('ors.pay_report_status','=',2);
                });
            }else{
                $query->where('ors.clear_status','=',$body['clear_status']);
            }
        }
        
        
        if (isset($body['status']) && $body['status'] !='') {
            $query->where('o.status','=',$body['status']);
        }
        
        if (isset($body['is_return']) && $body['is_return'] !='') {
            $returnfalg = $body['is_return']==1?'=':'>';
            $query->where('o.status',$returnfalg,0);
        }
        if (isset($body['serial_number']) && $body['serial_number'] !='') {
            $query->where('oes.serial_number','=',(int)$body['serial_number']);
            $query->where('o.cd','>=',strtotime(date('Y-m-d')));
        }
        
        if(isset($body['review']) && $body['review']!=''){
            $query->where('ors.clear_status','=',1);
            $reviewflag=$body['review']==1?'>':'=';
            $query->where('ors.delivery_status',$reviewflag,0);
             $query->where('o.status','>=',20);
//            if($body['review']==1){
//                 $query->where('o.status','=',50);
//            }else{
//                $query->where('o.status','>=',20);
//                $query->where('o.status','<',50);
//            }
        }
        $query->orderBy('o.id','desc');
        $select     = [
            'o.*',
            'm.account',
            'mi.nickname',
            'ors.clear_status',
            'ors.clear_time',
            'ors.express_status',
            'ors.express_time',
            'ors.pay_report_status',
            'ors.pay_report_time',
            'ors.delivery_status',
            'ors.delivery_time',
            'ors.express_type',
            'ors.express_report_data',
            'ors.express_code',
            'ors.express_name',
            'm.vip_level',
            'm.vip_expired',
            'o.guide_id',
        ];
        $pageInfo   = $query->paginate((int)$limit,$select, 'page', (int)$page,true)->toArray();

        $list       = $pageInfo['data'];
        $orderIds   = array_column($list,'id');
        
        //扩展
        $orderExtendsList = OrderService::instance()->queryOrderExtendsByIds($orderIds);
        $orderExtendsListMap = array_column($orderExtendsList,null,'order_id');
        
        
        //收银机
        $cashregister_ids       = array_column($orderExtendsList,'cashregister_id');
        $casherRegisterList     = CashManagerService::instance()->getCashRegisterByIds($cashregister_ids);
        $casherRegisterListMap  = array_column($casherRegisterList,null,'id');
        
        
        //收银员
        $casher_ids         = array_column($orderExtendsList,'casher');
        $casherList         = CashManagerService::instance()->getCasherByIds($casher_ids);
        $casherListMap      = array_column($casherList,null,'id');
        
        //获取下单商品数据
        $orderGoodsList     = OrderService::instance()->queryOrderGoodsByOrderIds($orderIds);
        $goodsIds           = array_column($orderGoodsList,'goods_id');
        $orderGoodsListMap  = getArrayGroupData($orderGoodsList,'order_id');
        
        //查询原始商品信息
        $goodsList          = ChannelGoodsService::instance()->queryGoodsList($goodsIds);
        $goodsListMap       = array_column($goodsList,null,'id');
        
        //储值卡信息
        $store_card_ids     = array_column($orderExtendsList,'storecard_id');
        $storeCardList      = StoreCardService::instance()->queryStoredCardByIds($store_card_ids);
        $storeCardListMap   = array_column($storeCardList,null,'id');
        
        //退款订单
        $orderSns = array_column($list,'sn');
        $orderRefundList = OrderService::instance()->queryOrderRefundBySns($orderSns);
        $orderRefundListMap = array_column($orderRefundList,null,'sn');
        
        $provinceIds        = array_column($orderExtendsList,'express_province');
        $cityIds            = array_column($orderExtendsList,'express_city');
        $areaIds            = array_column($orderExtendsList,'express_area');
        $allAreaIds         = array_merge($provinceIds,$cityIds,$areaIds);
        $areaListMap        = AreaService::instance()->queryAreaListById($allAreaIds);
        
        //申报日志
        $reportLog      = ReportLogService::instance()->getLogByOrderIds($orderIds);

        //供应商
        $supply_lists   = YunCangSupplier::instance()
            ->where(['cid' => $cid])
            ->where('supplier_name','<>','')
            ->get()->toArray();
        $supply_lists_map = array_column($supply_lists,null,'id');
        
        $data = [];
        foreach ($list as $key => $value)
        {
            $order_id = $value['id'];
            $order_sn = $value['sn'];
            $orderextends = $orderExtendsListMap[$order_id] ?? [];
            if( isset($orderextends['cashregister_id']) ) 
            {
                $cashregister   = $casherRegisterListMap[$orderextends['cashregister_id']] ?? [];
                $casher         = $casherListMap[$orderextends['casher']] ?? [] ;
                $storecardinfo  = $storeCardListMap[$orderextends['storecard_id']] ?? [] ;
            }
            
            $orderGoodsList = $orderGoodsListMap[$order_id];
            foreach ($orderGoodsList as & $goods)
            {
                $goods['barcode'] = $goodsListMap[$goods['goods_id']]['barcode'] ?? '未定义';
                $goods['skucode'] = $goodsListMap[$goods['goods_id']]['skucode'] ?? '未定义';

/*                $goods['price']     = $goods['price'] / $goods['num'];
                $goods['price_vip'] = $goods['price_vip'] / $goods['num'];*/
                if($goods['is_combine_goods'] == 1){ //组合商品
                    $single_goods              = $goods;
                    $single_goods['price_pay'] = $goods['price']; //普通用户单价

                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods, 1);
                    $price_tax                 = $combine_goods['price_total_tax'];//销售税金
                    $price                     = $goods['price'] - $price_tax;
                    $real_price_pay_tax        = $price_tax;

                    $single_goods['price_pay'] = $goods['price_vip']; //会员用户单价
                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods);
                    $price_vip_tax             = $combine_goods['price_total_tax'];//销售税金
                    $price_vip                 = $goods['price_vip'] - $price_vip_tax;

                }else{
                    if($goods['tax_rate']==0){
                        $goods['tax_rate']=$goodsListMap[$goods['goods_id']]['tax_rate'];
                    }
                    $taxflag            = bcadd('1', (string)$goods['tax_rate'],3);
                    $price              = bcdiv((string)$goods['price'], (string)$taxflag, 3);
                    $price_vip          = bcdiv((string)$goods['price_vip'], (string)$taxflag, 3);
                    $price              = number_format((float)$price,2,'.','');
                    $price_vip          = number_format((float)$price_vip,2,'.','');
                    $price_tax          = bcsub((string)$goods['price'], (string)$price,2);
                    $price_vip_tax      = bcsub((string)$goods['price_vip'], (string)$price_vip,2);

                    //真实销售税费
                    $real_price_pay_tax = (new CashGoodsService())->singGoodsPriceFree($goods['price'],$goods);

                }

                $goods['real_price_pay_tax'] = $real_price_pay_tax ?? 0;
                $goods['old_price_tax']      = $price_tax;
                $goods['old_price_vip_tax']  = $price_vip_tax;
                $goods['old_price']          = $price;
                $goods['old_price_vip']      = $price_vip;
                $goods['supplier_name']      = $supply_lists_map[$goods['supplier_id']]['supplier_name'] ?? '';


                $goods['price_tax']    = round($goods['price_tax'] / $goods['num'], 2);
            }
            if($value['vip_level']==1 && $value['vip_expired']>time()){
                $is_vip     =2;
                $vip_type   ="黑卡会员";
            }elseif($value['vip_level']==2 && $value['vip_expired']>time()){
                $is_vip     =2;
                $vip_type   ="高级会员";
            }elseif($value['account']){
                $is_vip     =1;
                $vip_type   ="普通会员";
            }else{
                $is_vip     =0;
                $vip_type   ="-";
            }

            //导购员
            $guide_name = ShoppingGuide::instance()
                ->where(['id' => $value['guide_id']])
                ->value('name');
            $data[]=[
                'id'=>$value['id'],
                'cd'=>$value['cd'],
                'sn'=>$value['sn'],
                'status'=>$value['status'],
                'pay_sn'=>$value['pay_sn'],
                'pay_serial'=>$value['pay_serial'],
                'pay_time'=>$value['pay_time']?date('Y-m-d H:i:s',$value['pay_time']):'',
                'account'=>$value['account'],
                'vip_level'=>$vip_type,
                'nickname'=>$value['nickname'],
                'return'=> empty($orderRefundListMap[$order_sn])?0:1,
                'price_total'=>$value['price_total'],
                'price_order'=>$value['price_order'],
                'goods_num'=>$value['goods_num'],
                'order_message'=>$value['order_message'],
                'giveup_money'=>$orderextends['giveup_money'],
                'pay_way'=>explode(',', $orderextends['pay_way']),
                'cash'=>$orderextends['cash'],
                'scan_pay'=>$orderextends['scan_pay'],
                'scan_rece'=>$orderextends['scan_rece'],
                'pos'=>$orderextends['pos'],
                'storecard'=>$orderextends['storecard'],
                'storecard_num'=>$orderextends['storecard_id']?$storecardinfo['number']:'',
                'storecard_id'=>$orderextends['storecard_id'],
                'balance'=>$orderextends['balance'],
                'coupon'=>$orderextends['coupon'],
                'goods_points'=>$orderextends['goods_points'],
                'price_coupon'=>$value['price_coupon'],
                'points'=>$orderextends['points'],
                'cashregister'=>$cashregister['name'] ??'',
                'casher_id'=>$orderextends['casher'],
                'casher'=>$casher['name'] ??'',
                'goods'=>$orderGoodsList,
                'tax_fee'=>$value['tax_fee'],
                'cash_receive'=>$orderextends['cash_receive']??0,
                'cash_reback'=>$orderextends['cash_reback']??0,
                'total_vipDiscount'=>$value['total_vipDiscount'],
                'total_fullReduction'=>$value['total_fullReduction'],
                'total_goodsReduction'=>$value['total_goodsReduction'],
                'total_priceSpecial'=>$value['total_priceSpecial'],
                'total_discount'=>$value['total_discount'],
                'total_orderActivity'=>$value['total_orderActivity'],
                'total_modifyDiscount'=>$value['total_modifyDiscount'],
                'express_num'=>$value['express_num'],
                'mobile'=>$value['buyer_mobile'],
                'buyer_mobile'=>$value['buyer_mobile'],
                'buyer_name'=>$value['buyer_name'],
                'buyer_idcard'=>StringService::hide_idcard($value['buyer_idcard']),
                'express_type'=>$orderextends['express_type'],
                'express_province'=>$orderextends['express_province']?$areaListMap[$orderextends['express_province']]['name']:'',
                'express_city'=>$orderextends['express_city']?$areaListMap[$orderextends['express_city']]['name']:'',
                'express_area'=>$orderextends['express_area']?$areaListMap[$orderextends['express_area']]['name']:'',
                'express_address'=>$orderextends['express_address'],
                'express_name'=>$orderextends['express_name'],
                'express_mobile'=>$orderextends['express_mobile'],
                'serial_number'=>str_pad((string)$orderextends['serial_number'], 4, '0', STR_PAD_LEFT),
                'user_pay_type'=>$orderextends['user_pay_type']?OrderService::instance()->user_pay_type[$orderextends['user_pay_type']]:'',
                'clear_status'=>$value['clear_status'],
                'clear_time'=> $value['clear_time']?date('Y-m-d H:i:s',$value['clear_time']):'',
                'express_status'=>$value['express_status'],
                'express_time'=> $value['express_time']?date('Y-m-d H:i:s',$value['express_time']):'',
                'pay_report_status'=>$value['pay_report_status'],
                'pay_report_time'=> $value['pay_report_time']?date('Y-m-d H:i:s',$value['pay_report_time']):'',
                'order_report_status'=>$value['clear_status']==2?1:$value['clear_status'],
                'order_report_time'=> $value['clear_time']?date('Y-m-d H:i:s',$value['clear_time']):'',
                'delivery_status'=>$value['delivery_status'],
                'delivery_time'=>$value['delivery_status']?date('Y-m-d H:i:s',$value['delivery_status']):'',
                'reportlog'=>$reportLog[$value['id']]??[],
                'express_report_code'=>$value['express_code'],
                'express_report_name'=>$value['express_name'],
                'express_report_type'=>$value['express_type'],
                'express_report_data'=>$value['express_report_data'],
                'guide_name' => $guide_name,
                'type' => $value['type'],
            ];
        }
        return Normal::returnCode(Normal::SUC, '成功', [
            'list'          => $data,
            'totalcount'    => $pageInfo['total']
        ]);
    }


    /**
     * 退货订单查询
     * @param int $cid
     * @param int $mn_sid
     * @param $body
     * @return array
     */
    public function returnOrderList(int $cid,int $mn_sid,$body){
        $page  = $body['page']  ?? 1;
        $limit = $body['limit'] ?? 10;
        $query = OrderReturn::instance()
            ->from(OrderReturn::instance()->getTable() . ' as o')
            ->leftJoin('ly_member as m','o.mid','=','m.mid')
            ->leftJoin('ly_member_info as mi','o.mid','=','mi.mid')
            ->order('o.id desc')
            ->where([
                'o.mn_sid' => $mn_sid,
//                'o.type'   => 3,
                'check_status' => 1
            ])
            ->whereIn('o.type',[3,4]);

        if (!empty($body['search'])) {
            $search = '%'.$body['search'].'%';
            $query->where(function ($query_or) use ($search){
                $query_or->orWhere('o.sale_sn','like',$search)
                    ->orWhere('o.sn','like',$search)
                    ->orWhere('m.account','like',$search);
            });
        }
        if (!empty($body['starttime'])) {
            $query->where('o.cd', '>=', strtotime($body['starttime']));
        }
        if (!empty($body['endtime'])) {
            $query->where('o.cd', '<=', strtotime($body['endtime']));
        }
        $select     = [
            'o.*',
            'm.account',
            'mi.nickname'
        ];
        $pageInfo   = $query->paginate((int)$limit,$select, 'page', (int)$page,true)->toArray();
        $list       = $pageInfo['data'];

        $orderSns   = array_column($list,'sn');
        $orderList  = OrderService::instance()->queryOrdersBySn($orderSns,[
            'id','cd','sn','price_total','price_order','goods_num','order_message'
        ]);
        $orderListMap = array_column($orderList,null,'id');
        $orderIds = array_keys($orderListMap);
        //扩展
        $orderExtendsList = OrderService::instance()->queryOrderExtendsByIds($orderIds);
        $orderExtendsListMap = array_column($orderExtendsList,null,'order_id');

        //收银机
        $cashregister_ids       = array_column($orderExtendsList,'cashregister_id');
        $casherRegisterList     = CashManagerService::instance()->getCashRegisterByIds($cashregister_ids);
        $casherRegisterListMap  = array_column($casherRegisterList,null,'id');

        //收银员
        $casher_ids         = array_column($orderExtendsList,'casher');
        $casherList         = CashManagerService::instance()->getCasherByIds($casher_ids);
        $casherListMap      = array_column($casherList,null,'id');

        //获取下单商品数据
        $orderGoodsList     = OrderService::instance()->queryOrderGoodsByOrderIds($orderIds);
        $goodsIds           = array_column($orderGoodsList,'goods_id');
        $orderGoodsListMap  = getArrayGroupData($orderGoodsList,'order_id');

        //查询原始商品信息
        $goodsList          = ChannelGoodsService::instance()->queryGoodsList($goodsIds);
        $goodsListMap       = array_column($goodsList,null,'id');

        //商品
        $data=[];
        foreach ($list as $value) {
            $orderInfo = $orderListMap[$value['sn']] ?? [];
            if (empty($orderInfo)){
                continue;
            }
            $orderextends = $orderExtendsListMap[$orderInfo['id']] ?? [];
            if (empty($orderextends)){
                continue;
            }
            $casherRegister = $casherRegisterListMap[$orderInfo['id']] ?? [];
            $casher         = $casherListMap[$orderInfo['id']] ?? [];

            $orderGoodsList = $orderGoodsListMap[$orderInfo['id']];
            foreach ($orderGoodsList as & $goods)
            {
                $goods['barcode'] = $goodsListMap[$goods['goods_id']]['barcode'] ?? '未定义';
                $goods['skucode'] = $goodsListMap[$goods['goods_id']]['skucode'] ?? '未定义';
            }
            $data[]=[
                'id'=>$orderInfo['id'],
                'cd'=>$orderInfo['cd'],
                'sn'=>$value['sn'],
                'account'=>$value['account'],
                'nickname'=>$value['nickname'],
                'price_total'=>$orderInfo['price_total'],
                'price_order'=>$orderInfo['price_order'],
                'goods_num'=>$orderInfo['goods_num'],
                'order_message'=>$orderInfo['order_message'],
                'giveup_money'=> $orderextends['giveup_money'] ?? 0,
                'pay_way'=>explode(',', $orderextends['pay_way'] ),
                'cash'=>$orderextends['cash'],
                'scan_pay'=>$orderextends['scan_pay'],
                'scan_rece'=>$orderextends['scan_rece'],
                'pos'=>$orderextends['pos'],
                'storecard'=>$orderextends['storecard'],
                'balance'=>$orderextends['balance'],
                'coupon'=>$orderextends['coupon'],
                'points'=>$orderextends['points'],
                'cashregister'=>$casherRegister['name'] ?? '',
                'casher_id'=>$orderextends['casher'],
                'casher'=>$casher['name'],
                'goods'=>$orderGoodsList
            ];
        }
        return Normal::returnCode(Normal::SUC, '成功',
            ['list'=>$data,'totalcount' => $pageInfo['total']]);
    }
    /**
     * 退货
     **/
    public function returnOrder(int $cid,int $mn_sid,array $body=[]){
        $mid=isset($body['mid'])?$body['mid']:0;
        $cashregister_id=$body['cashregister_id'];
        $casher=$body['casher'];
        $time=$body['time']??time();
        $sale_sn=isset($body['sn'])?$body['sn']:Billcode::returnCode('', $mn_sid);
        $res= $this->returncheck($body);
        if($res['code']== Normal::FAIL){
            return $res;
        }
        $body=$res['data'];
        $mid=$body['mid'];
        $ChannelWx = ChannelWx::instance()->info(['cid' => $cid]);
        $pushdata=['appid'=>$ChannelWx['stb_app_id'],'requestMethod'=>'bbcOrderAfterSale','requestData'=>['order_sn'=>$body['sn'],'cid'=>$cid,'exceptReason'=>'门店收银退货','after_sale_status'=>1]];
        $orderreturndata=[
            'sale_type'=>2,
            'sn'=>$body['sn'],
            'reason'=>'其他原因',
            'reason_info'=>'门店收银退货',
            'sale_sn'=>$sale_sn,
            'cd'=>$time,
            'status'=>1,
            'amount'=>$body['price_order'],
            'check_status'=>1,
            'mid'=>$mid,
            'mn_sid'=>$body['mn_sid'],
            'cid'=>$body['cid'],
            'pay_type'=>$body['pay_type'],
            'stoid'=>$body['stoid'],
            'mnid'=>4,
            'return_money'=>1,
            'type'=>$body['type']
        ];
        $extendsdata=[
            'order_id'=>$body['id'],
            'cd'=>$time,
            'cid'=>$body['cid'],
            'mn_sid'=>$body['mn_sid'],
            'giveup_money'=>0,
            'pay_way'=> implode(',', $body['pay_way']),
            'cash'=> isset($body['cash'])?$body['cash']:0,
            'scan_pay'=> isset($body['scan_pay'])?$body['scan_pay']:0,
            'scan_rece'=> isset($body['scan_rece'])?$body['scan_rece']:0,
            'pos'=> isset($body['pos'])?$body['pos']:0,
            'storecard'=> isset($body['storecard'])?$body['storecard']:0,
            'storecard_id'=> isset($body['storecard_id'])?$body['storecard_id']:0,
            'balance'=> isset($body['balance'])?$body['balance']:0,
            'coupon'=> isset($body['coupon'])?$body['coupon']:0,
            'points'=> isset($body['points'])?$body['points']:0,
            'cashregister_id'=>$cashregister_id,
            'casher'=>$casher,
            'give_points'=>$body['orderextends']['give_points']??0
        ];
        Order::instance()->startTrans();
        try{
            $orderres= Order::instance()->edit(['id'=>$body['id']], ['status'=>0,'md'=>$time]);
            if(!$orderres){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '原始订单修改失败');
            }
            $orderreturnres= OrderReturn::instance()->add($orderreturndata);
            if(!$orderreturnres){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '退货单新增失败');
            }
            $extendsdata['order_return_id']=$orderreturnres;
            $orderreturnextendsres= OrderReturnExtends::instance()->add($extendsdata);
            if(!$orderreturnextendsres){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '退货单扩展新增失败');
            }
            if($mid>0){
                $memberconsumeres= Member::instance()->where(['mid'=>$mid])->setDec('consume',$body['price_order']);
                if(!$memberconsumeres){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '更新累计消费失败');
                }
            }
            /**
             * 在线支付原路退货
             */
            if($extendsdata['scan_rece']){
                //退款 todo
                $pay= Payreturn::instance()->index(['scan_rece_type'=>$body['orderextends']['scan_rece_type'],'out_refund_no'=>$sale_sn,'out_trade_no'=>$body['sn'],'body'=>'门店付款','total_fee'=>$extendsdata['scan_rece'],'cid'=>$cid,'scan_sn'=>$body['orderextends']['scan_sn']]);
                if($pay['status']!=200){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, $pay['msg']);
                }
            }
            /**
             * 储值卡积分
             */
            if($extendsdata['points']){
                $memberinfo= Member::instance()->info(['mid'=>$mid]);
                $memberpointsres= Member::instance()->where(['mid'=>$mid])->setInc('points',$extendsdata['points']);
                if(!$memberpointsres){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡积分退款失败1');
                }
                $pointslog= PointsLog::instance()->add([
                    'cid'=>$cid,
                    'mid'=>$mid,
                    'type'=>1,
                    'points'=>$extendsdata['points'],
                    'mn_sid'=>$mn_sid,
                    'cd'=>time(),
                    'remark'=>'线下退货退款'
                ]);
                if(!$pointslog){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡积分退款失败2');
                }
            }
            if($extendsdata['give_points']>0){
                $memberpointsgiveres= Member::instance()->where(['mid'=>$mid])->setDec('points',$extendsdata['give_points']);
                if(!$memberpointsgiveres){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡积分赠送退款失败1');
                }
                $memberpointsgiveres2= Member::instance()->where(['mid'=>$mid])->setDec('points_history',$extendsdata['give_points']);
                if(!$memberpointsgiveres2){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡积分赠送退款失败11');
                }
                $pointsgivelog= PointsLog::instance()->add([
                    'cid'=>$cid,
                    'mid'=>$mid,
                    'type'=>0,
                    'points'=>$extendsdata['give_points'],
                    'mn_sid'=>$mn_sid,
                    'cd'=>time(),
                    'remark'=>'线下退货退赠送积分'
                ]);
                if(!$pointsgivelog){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡积分赠送退款失败2');
                }
            }
            /**
             * 储值卡消费
             */
            if($extendsdata['storecard_id']){
                $storecard= StoreCard::instance()->info(['id'=>$extendsdata['storecard_id']]);
                $storecardmoney= StoreCard::instance()->where(['id'=>$extendsdata['storecard_id']])->setInc('money',$extendsdata['storecard']);
                if(!$storecardmoney){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡返还失败1');
                }
                $storecardmoneyuse= StoreCard::instance()->where(['id'=>$extendsdata['storecard_id']])->setDec('money_use',$extendsdata['storecard']);
                if(!$storecardmoneyuse){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡返还失败2');
                }
                $storecardlog= StoreCardLog::instance()->add([
                    'cid'=>$body['cid'],
                    'mn_sid'=>$body['mn_sid'],
                    'order_number'=>$sale_sn,
                    'type'=>0,
                    'money'=>$extendsdata['storecard'],
                    'after_money'=> bcadd((string)$storecard['money'],(string)$extendsdata['storecard'],2),
                    'before_money'=>$storecard['money'],
                    'storecard_id'=>$extendsdata['storecard_id'],
                    'cd'=>$time
                ]);
                if(!$storecardlog){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '储值卡返还失败,日志');
                }
            }
            /**
             * 商品处理
             */
            foreach ($body['goods'] as $key => $value) {
                $batchs= json_decode($value['batch_actual'], true);
                $stockresult=Storage::instance()->addStock(['cid'=>$body['cid'],'mn_sid'=>$body['mn_sid'],'goods_id'=>$value['goods_id'],'bill_type'=>3,'bill_id'=>$orderreturnres,'bill_code'=>$sale_sn,'num'=>$value['num'],'batch_no'=>$batchs[0]['batch_no'],'expire'=>0,'time'=>$time]);
                if($stockresult['code']!= Normal::SUC){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, $stockresult['message']);
                }
            }
            /**
             * 处理分佣
             */
            $commission=MnCommission::instance()->lists(['sn'=>$body['sn'],'mn_sid'=>$body['mn_sid'],'df'=>0]);
            if(!empty($commission)){
                $qStore=Mnuser::instance()->info(['id'=>$body['mn_sid']]);
                if($commission[0]['status']==1){
                    //佣金已转入可提现金额
                    $qEditData=[
                        'wallet_income'=>$qStore['wallet_income']-$body['distribute_money'],
                        'wallet_accumulate_income'=>$qStore['wallet_accumulate_income']-$body['distribute_money'],
                        'all_sell'=>$qStore['all_sell']-$body['price_order']
                    ];
                    $budget['mid']=$qStore['mid'];
                    $budget['mn_sid']=$qStore['id'];
                    $budget['mnid']=$qStore['mnid'];
                    $budget['type']=0;
                    $budget['sn']=$body['sn'];
                    $budget['money']=$body['distribute_money'];
                    $budget['amount']=$qEditData['wallet_income'];
                    $budget['remark']='订单:'.$body['sn'].'售后退款';
                    $budget['cd']=$time;
                    $mnbudgetres=MnBudget::instance()->add($budget);
                    if(!$mnbudgetres){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, '退款记录写入失败');
                    }
                }else{
                    //佣金还未转入可提现金额
                    $qEditData=[
                        'frozen_income'=>$qStore['frozen_income']-$body['distribute_money'],
                        'all_sell'=>$qStore['all_sell']-$body['price_order']
                    ];
    
                }
                $mncommissionres=MnCommission::instance()->edit(['sn'=>$body['sn'],'mn_sid'=>$body['mn_sid']],['df'=>1]);
                if(!$mncommissionres){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '分佣记录更新失败');
                }
                $mnuserres=Mnuser::instance()->edit(['id'=>$body['mn_sid']],$qEditData);
                if(!$mnuserres){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, '用户资金更新失败');
                }
            }
            Order::instance()->commit();
            //            $pushreturndata= json_encode($pushdata, JSON_UNESCAPED_UNICODE);
            //            $orderpushid= \Ly\Model\OrderPush::instance()->edit(['sn'=>$sale_sn],['return_data'=>$pushreturndata]);
            //            \Ly\Model\Rbq::instance()->pushOrder($pushreturndata,'order','push');
            //            \Ly\Model\OrderPush::instance()->edit(['sn'=>$sale_sn],['is_return'=>1]);
            return Normal::returnCode(Normal::SUC, '操作成功',['sn'=>$sale_sn,'order_id'=>$orderreturnres]);
        } catch (\Exception $ex) {
            Order::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '失败'.$ex->getMessage());
        }
    }
    public function returncheck(array $body=[]){
        $order= Order::instance()->info(['id'=>$body['order_id']]);
        if(empty($order)){
            return Normal::returnCode(Normal::FAIL, '原始订单信息未找到');
        }
        if($order['status']==0){
            return Normal::returnCode(Normal::FAIL, '该订单已退货');
        }
        $ordergoods= OrderGoods::instance()->lists(['order_id'=>$order['id']]);
        $orderextends= OrderExtends::instance()->info(['order_id'=>$order['id']]);
        if(empty($body['pay'])){
            return Normal::returnCode(Normal::FAIL, '支付信息不能为空');
        }
        $pay= json_decode($body['pay'],TRUE);
        if(empty($pay)){
            return Normal::returnCode(Normal::FAIL, '支付信息有误');
        }
        $body=$order;
        $body['goods']=$ordergoods;
        $pay_way=[];
        foreach ($pay as $key => $value) {
            $pay_way[]=$value['pay_type'];
            switch ($value['pay_type']) {
                case 1:
                    $body['cash']=$value['pay_money'];
                    break;
                case 2:
                    $body['scan_pay']=$value['pay_money'];
                    break;
                case 3:
                    $body['scan_rece']=$value['pay_money'];
                    if($orderextends['scan_rece']!=$value['pay_money']){
                        return Normal::returnCode(Normal::FAIL, '扫码收款金额与消费金额不等');
                    }
                    break;
                case 4:
                    $body['pos']=$value['pay_money'];
                    break;
                case 5:
                    if($orderextends['storecard']!=$value['pay_money']){
                        return Normal::returnCode(Normal::FAIL, '储值卡退款金额与消费金额不等');
                    }
                    $body['storecard']=$value['pay_money'];
                    $body['storecard_id']=$orderextends['storecard_id'];
                    break;
                case 6:
                    $body['balance']=$value['pay_money'];
                    break;
                case 7:
                    $body['coupon']=$value['pay_money'];
                    break;
                case 8:
                    $body['points']=$value['pay_money'];
                    if(!isset($body['mid'])){
                        return Normal::returnCode(Normal::FAIL, '会员信息必传');
                    }
                    $member= \Ly\Model\Member::instance()->info(['mid'=>$body['mid']]);
                    if(empty($member)){
                        return Normal::returnCode(Normal::FAIL, '会员信息错误');
                    }
                    if($orderextends['points']!=$value['pay_money']){
                        return Normal::returnCode(Normal::FAIL, '储值卡积分与消费积分不等');
                    }
                    break;
                default:
                    break;
            }
        }
        $body['pay_way']=$pay_way;
        $body['orderextends']=$orderextends;
        return Normal::returnCode(Normal::SUC, '成功',$body);
    }

    /**
     * 自提单查询
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return array
     */
    public function selforderList(int $cid,int $mn_sid,array $body=[]){
        $page  = $body['page']  ?? 1;
        $limit = $body['limit'] ?? 10;
        $query = Order::instance()
            ->from(Order::instance() . ' as o')
            ->leftJoin('ly_member as m','o.mid','=','m.mid')
            ->leftJoin('ly_member_info as mi','o.mid','=','mi.mid')
            ->order('o.id desc')
            ->where([
                'o.df' => 0,
                'o.mn_sid' => $mn_sid,
                'o.type' => 2,
            ])
            ->where('o.status','>=',20);

        $mnuser= Mnuser::instance()->info(['id'=>$mn_sid]);
        $stocktype = $mnuser['stock_share']==1?1:2;

        if (isset($body['search']) && $body['search'] !='') {
            $search = '%'.$body['search'].'%';
            $query->where(function ($query_or) use ($search){
                $query_or->orWhere('o.sn','like',$search)
                    ->orWhere('m.account','like',$search);
            });
        }
        if (!empty($body['starttime'])) {
            $query->where('o.cd', '>=', strtotime($body['starttime']));
        }
        if (!empty($body['endtime'])) {
            $query->where('o.cd', '<=', strtotime($body['endtime']));
        }

        if (isset($body['status']) && $body['status'] !='') {
            $query->where('o.status',$body['status']);
        }

        $select     = [
            'o.*',
            'm.account',
            'mi.nickname'
        ];
        $pageInfo   = $query->paginate((int)$limit,$select, 'page', (int)$page,true)->toArray();
        $list       = $pageInfo['data'];

        $orderIds   = array_column($list,'id');

        //获取下单商品数据
        $orderGoodsList     = OrderService::instance()->queryOrderGoodsByOrderIds($orderIds);
        $goodsIds           = array_column($orderGoodsList,'goods_id');
        $orderGoodsListMap  = getArrayGroupData($orderGoodsList,'order_id');

        //查询原始商品信息
        $goodsList          = ChannelGoodsService::instance()->queryGoodsList($goodsIds);
        $goodsListMap       = array_column($goodsList,null,'id');

        //获取商品批次
        $goodsBatchList     = Goodsbatch::instance()
            ->select(['id as batch_id','batch_no','num','expired_date','goods_id'])
            ->where('mn_sid',$mn_sid)->where('num','>',0)->where('type',$stocktype)
            ->whereIn('goods_id',array_keys($goodsListMap))
            ->get()->toArray();
        $goodsBatchListMap = array_column($goodsBatchList,null,'goods_id');

        //获取退货单
        $sns = array_column($list,'sn');
        $orderReturnListArray = OrderReturn::instance()->select(['sn'])->whereIn('sn',$sns)->whereIn('check_status',[0,1,4])->pluck('sn');

        $data=[];
        foreach ($list as $value) {

            $orderGoodsList = $orderGoodsListMap[$value['id']];
            foreach ($orderGoodsList as & $goods)
            {
                $goods['barcode'] = $goodsListMap[$goods['goods_id']]['barcode'] ?? '未定义';
                $goods['skucode'] = $goodsListMap[$goods['goods_id']]['skucode'] ?? '未定义';
                $goods['batch']   = $goodsBatchListMap[$goods['goods_id']] ?? [];
            }

            $data[]=[
                'id'=>$value['id'],
                'cd'=>$value['cd'],
                'sn'=>$value['sn'],
                'account'=>$value['account'],
                'nickname'=>$value['nickname'],
                'return'=> in_array($value['sn'],$orderReturnListArray)?0:1,
                'price_total'=>$value['price_total'],
                'price_order'=>$value['price_order'],
                'goods_num'=>$value['goods_num'],
                'status'=>$value['status'],
                'self_time'=>$value['self_time'],
                'shipping_time'=>$value['shipping_time'],
                'order_message'=>$value['order_message'],
                'goods'=> $orderGoodsList
            ];
        }
        return Normal::returnCode(Normal::SUC, '成功', ['list'=>$data,'totalcount' => $pageInfo['total']]);
    }


    /**
     * 自提单核销
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return array
     */
    public function selfOrderReview(int $cid,int $mn_sid,array $body=[]){

        $order= Order::instance()->info(['mn_sid'=>$mn_sid,'id'=>$body['order_id']]);
        if(empty($order)){
            return Normal::returnCode(Normal::FAIL, '未找到相关订单');
        }

        if($order['status']==40){
            return Normal::returnCode(Normal::FAIL, '该订单已经提货');
        }

        if($order['self_code']!=$body['self_code']){
            return Normal::returnCode(Normal::FAIL, '自提码错误');
        }

        $goods= json_decode($body['goods'],true);
        if(empty($goods)){
            return Normal::returnCode(Normal::FAIL, '自提商品批次信息不能为空');
        }

        $mnuserInfo= Mnuser::instance()->info(['id'=>$mn_sid]);

        //查询
        $orderGoodsIds = array_column($goods,'order_goods_id');
        $orderGoodsList = OrderGoods::instance()->whereIn('id',$orderGoodsIds)->get()->toArray();
        $orderGoodsListMap = array_column($orderGoodsList,null,'id');

        Order::instance()->startTrans();

        try{

            foreach ($goods as $value) {

                $batchNum = array_sum(array_column($value['batch'], 'num'));
                $orderGoods = $orderGoodsListMap[$value['order_goods_id']];
                //判断是否存在商品
                if(empty($orderGoods)){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'订单商品信息有误');
                }
                //判断商品数量是否有误
                if($orderGoods['num']!=$batchNum){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'自提商品批次信息有误');
                }

                $batchIds = array_column($value['batch'],'batch_id');
                $goodsBatchList = GoodsBatch::instance()->whereIn('id',$batchIds)->get()->toArray();
                $goodsBatchMap  = array_column($goodsBatchList,null,'id');

                $batchs=[];
                foreach ($value['batch'] as $v) {

                    $goodsBatch= $goodsBatchMap[$v['batch_id']] ?? [];
                    if(empty($goodsBatch)){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'自提商品批次信息有误2');
                    }

                    if($goodsBatch['num']<$v['num']){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'【'.$goodsBatch['batch_no'].'】批次库存不足');
                    }

                    $goodsBatchre= Goodsbatch::instance()
                        ->where(['id'=>$v['batch_id']])
                        ->setDec('num',$v['num']);

                    if(!$goodsBatchre){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'【'.$goodsBatch['batch_no'].'】批次库存扣减失败');
                    }
                    $batchs[]= ['batch_id'=>$v['batch_id'],'batch_no'=>$goodsBatch['batch_no'],'num'=>$v['num']];
                }

                if($mnuserInfo['stock_share']==1){
                    $mnstoreGoodsRes = MnStoreGoods::instance()->where(['goods_id'=>$orderGoods['goods_id'],'mn_sid'=>$mn_sid])->setDec('quantity',$orderGoods['num']);
                    if(!$mnstoreGoodsRes){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'库存扣取失败');
                    }
                } else {
                    $mnstoreGoodsRes= MnStoreGoods::instance()->where(['goods_id'=>$orderGoods['goods_id'],'mn_sid'=>$mn_sid])->setDec('onlinequantity',$orderGoods['num']);
                    if(!$mnstoreGoodsRes){
                        Order::instance()->rollback();
                        return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'库存扣取失败');
                    }
                }
                $orderGoodsRes= OrderGoods::instance()->edit(['id'=>$value['order_goods_id']], ['batch_actual'=> json_encode($batchs)]);
                if(!$orderGoodsRes){
                    Order::instance()->rollback();
                    return Normal::returnCode(Normal::FAIL, $orderGoods['goods_name'].'订单商品更新失败');
                }
            }
            $orderGoodsCount= OrderGoods::instance()->countNum(['order_id'=>$body['order_id'],'batch_actual'=>NULL]);
            if($orderGoodsCount>0){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '核销失败,订单商品数量不匹配');
            }
            $orderres= Order::instance()->edit(['id'=>$body['order_id']], ['status'=>40,'shipping_time'=>time(),'self_review'=>$body['casher']]);
            if(!$orderres){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '核销失败');
            }
            $log = [
                'order_id' => $order['id'], 'order_status' => 40, 'msg' => '自动收货'
            ];
            $orderlogres= OrderLog::instance()->insertlog($log);
            if(!$orderlogres){
                Order::instance()->rollback();
                return Normal::returnCode(Normal::FAIL, '订单日志更新失败');
            }
            $now = time();
            if ($order['cid'] > 0) {
                $day=MnCommission::instance()->day;
                $config= ConfigChannel::instance()->info(['code'=>'settle_bill_day','cid'=>$order['cid']]);
                if(!empty($config)){
                    $value=json_decode($config['value'],true);
                    $day=$value['day']??MnCommission::instance()->day;
                }
                $time =$now + $day * 86400;
                $mncommissionres=MnCommission::instance()->edit(['sn' => $order['sn']], ['thaw_time' => $time]);
                //                if(!$mncommissionres){
                //                    Order::instance()->rollback();
                //                    return Normal::returnCode(Normal::FAIL, '订单分佣更新失败');
                //                }
                $resselfcommissionres=SelfBuyCommission::instance()->edit(['sn' => $order['sn']], ['thaw_time' => $time]);
                //                if(!$resselfcommissionres){
                //                    Order::instance()->rollback();
                //                    return Normal::returnCode(Normal::FAIL, '分佣记录更新失败');
                //                }
            }
            Order::instance()->commit();
            return Normal::returnCode(Normal::SUC, '核销成功');
        } catch (\Exception $ex) {
            Order::instance()->rollback();
            return Normal::returnCode(Normal::FAIL, '失败'.$ex->getMessage());
        }
    
    }
    
    /**
     *
     * 订单核销
     */
    public function bondedSelfOrderReview($cid,$mn_sid,$body) 
    {
        if(isset($body['express_num'])&&$body['express_num']!=''){
            $order= Order::instance()->info(['mn_sid'=>$mn_sid,'express_num'=>$body['express_num']]);
            if($order){
                if($order['status']==50){
                    return Normal::returnCode(Normal::FAIL, '该订单已经核销');
                }elseif($order['status']<20){
                    return Normal::returnCode(Normal::FAIL, '该订单已取消');
                }else{
                    $order_report_status= OrderReportStatus::instance()->info(['order_id'=>$order['id']]);
                    if($order_report_status){
                        if($order_report_status['clear_status']==1){
                            if($order_report_status['delivery_status']!=0){
                                return Normal::returnCode(Normal::SUC, '该订单已经核销');
                            }
                            $memberinfo= Member::instance()->info(['mid'=>$order['mid']]);
                            Order::instance()->startTrans();
                             try{
                                $orderReportRes=OrderReportStatus::instance()->edit(['id'=>$order_report_status['id']], ['delivery_status'=>2,'delivery_time'=>time(),'md'=>time()]);
                                if(!$orderReportRes){
                                    Order::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL, '失败,核销状态');
                                }
                                $orderres= Order::instance()->edit(['id'=>$order['id']], ['status'=>50,'md'=>time(),'receive_time'=>time()]);
                                if(!$orderres){
                                    Order::instance()->rollback();
                                    return Normal::returnCode(Normal::FAIL, '失败,订单状态');
                                }
                                if($order['return_goods_points']>0){
                                    $goodsPointsRes= GoodsPointsService::instance()->addGoodsPoints($cid, $order['mid'], $mn_sid, $order['return_goods_points'], $order['sn'], "购物返积分(订单号:{$order['sn']})");
                                    if($goodsPointsRes['code']==Normal::FAIL){
                                        Order::instance()->rollback();
                                        return $goodsPointsRes;
                                    }
                                }
                                if($order['return_parent_points']>0&&$memberinfo['parent_id']>0){
                                    $goodsparentPointsRes= GoodsPointsService::instance()->addGoodsPoints($cid, $memberinfo['parent_id'], $mn_sid, $order['return_parent_points'], $order['sn'], "下级购物返积分(订单号:{$order['sn']})");
                                    if($goodsparentPointsRes['code']==Normal::FAIL){
                                        Order::instance()->rollback();
                                        return $goodsparentPointsRes;
                                    }
                                }
                                Order::instance()->commit();
                                return Normal::returnCode(Normal::SUC, '核销成功');
                             } catch (\Exception $ex) {
                                Order::instance()->rollback();
                                return Normal::returnCode(Normal::FAIL, '失败'.$ex->getMessage());
                            }
                        }elseif($order_report_status['clear_status']==2){
                            return Normal::returnCode(Normal::FAIL, '该订单清关失败');
                        }elseif($order_report_status['clear_status']==0){
                            return Normal::returnCode(Normal::FAIL, '该订单还在清关中');
                        }
                    }else{
                        return Normal::returnCode(Normal::FAIL, '单号有误');
                    }
                }
            }else{
                return Normal::returnCode(Normal::FAIL, '未找到订单');
            }
        }else{
            return Normal::returnCode(Normal::FAIL, '物流单号参数必传');
        }
    }
    
    /**
     * 获取订单号
     * @param int $mn_sid
     */
    public function getBuilderSn( int $mn_sid) 
    {
        return CodeBuilder::getCode($mn_sid);
    }
    
    /**
     * 重推运单(含如果未推云仓订单和支付就继续推)
     * @param type $param
     * @return type
     */
    public function reportAgain($param) {
        if(empty($param['order_id'])){
            return Normal::returnCode(Normal::FAIL, '订单编号必传');
        }
        $order= Order::instance()->info(['id'=>$param['order_id']]);
        if(empty($order)){
            return Normal::returnCode(Normal::FAIL, '单号有误');
        }
        if($order['type']!=4){
            return Normal::returnCode(Normal::FAIL, '不受支持的订单类型');
        }
        $order_report= OrderReportStatus::instance()->info(['order_id'=>$order['id']]);
        if(empty($order_report)){
            return Normal::returnCode(Normal::FAIL, '申报信息有误');
        }
        $pushagain= PushAgain::instance()->info(['order_id'=>$order['id']]);
        if(empty($order['express_num'])){
            $way_bill_data = [
                'cid'               => $order['cid'],
                'mn_sid'            => $order['mn_sid'],
                'order_id'          => $order['id'],
                'order_sn'          => $order['sn'],
                'order_report_id'   => $order_report['id'],
                'time'              => time()
            ];
            $logisticReport = WayBillDeclareService::instance()->wayBillDeclare($way_bill_data);
            
            if($logisticReport['code']==Normal::SUC && $pushagain){
                $paydata= json_decode($pushagain['pay_data'],true);
                $paydata["logisticNo"]             = $logisticReport['data']['waybillNo'] ??'';
                $paydata["logisticCode"]           = $logisticReport['data']['logisticCustomCode']??"";
                $paydata["logisticName"]           = $logisticReport['data']['logisticCustomName']??'';
                $paydata["logisticWayBillContent"] = $logisticReport['data']['originData']??'';
                PushAgain::instance()->edit(['order_id'=>$order['id']],['pay_data'=>json_encode($paydata, JSON_UNESCAPED_UNICODE)]);
                $pushagain['pay_data']=json_encode($paydata, JSON_UNESCAPED_UNICODE);
            }
        }else{
            $logisticReport = WayBillDeclareService::instance()->pushLogisticDeclare($order['id'],$order_report['express_type']);
            if($logisticReport['code']==Normal::SUC && $pushagain){
                $paydata= json_decode($pushagain['pay_data'],true);
                $paydata["logisticCode"]           = $logisticReport['data']['logisticCustomCode']??"";
                $paydata["logisticName"]           = $logisticReport['data']['logisticCustomName']??'';
                PushAgain::instance()->edit(['order_id'=>$order['id']],['pay_data'=>json_encode($paydata, JSON_UNESCAPED_UNICODE)]);
                $pushagain['pay_data']=json_encode($paydata, JSON_UNESCAPED_UNICODE);
                OrderReportStatus::instance()->edit(['id'=>$order_report['id']],['express_code'=>$paydata["logisticCode"],'express_name'=>$paydata["logisticName"],'express_status'=>1,'express_time'=>time()]);
                $logisticdata = [
                    'order_id'  => $param['order_id'],
                    'sn'        => $order['sn'],
                    'cd'        => time(),
                    'content'   => '运单申报成功'
                ];
                OrderReportLog::instance()->add($logisticdata);
            }
        }
        if($logisticReport['code']!= Normal::SUC){
            return $logisticReport;
        }
        if($order['push_success']==0 && $pushagain && $order_report['pay_report_status']==1){
            $push_order_create_result=PushYunCangApiService::instance()->pushYunCangOrderByPushAgain($order['cid'], $pushagain);
            if($push_order_create_result['code']!=Normal::SUC){
                return $push_order_create_result;
            }
//            $orderCreateData= json_decode($pushagain['sync_data'],true);
//            $push_order_create_result = PushYunCangApiService::instance()->push($order['cid'],'createOrder',$orderCreateData);
//            if($push_order_create_result['code']==Normal::SUC){
//                $returnData = $push_order_create_result['data']['orderItems'];
//                $return_sn = [];
//                foreach ($returnData as $v) {
//                    $skuCodes = array_column($v['goods_items'], 'goodsSku');
//                    foreach ($skuCodes as $value) {
//                        $return_sn[$value] = $v['orderNo'];
//                    }
//                }
//                
//                Order::instance()->edit(['id'=>$order['id']], ['push_success'=>1]);
//                $editgoods= OrderGoods::instance()->lists(['order_id'=>$order['id']]);
//                foreach ($editgoods as $k => $v) 
//                {
//                    $stb_sn = $return_sn[$v['skucode']];
//                    OrderGoods::instance()->edit(['id'=>$v['id']], ['stb_sn'=>$stb_sn]);
//                }
//            }else{
//                return $push_order_create_result;
//            }
        }
        
        if($order['pay_success']==0 && $pushagain && $order_report['pay_report_status']==1){
            $pushPayResult=PushYunCangApiService::instance()->pushYunCangPayByPushAgain($order['cid'], $pushagain);
            if( $pushPayResult['code'] != Normal::SUC ){
                return $pushPayResult;
            }
//            $orderPayData= json_decode($pushagain['pay_data'],true);
//            $pushPayResult = PushYunCangApiService::instance()->push($order['cid'],'OrderPay',$orderPayData);
//            if( $pushPayResult['code'] == Normal::SUC )
//            {
//                Order::instance()->edit(['id'=>$order['id']], ['pay_success'=>1]);
//            }else{
//                return $pushPayResult;
//            }
        }
        return Normal::returnCode(Normal::SUC, '成功');
    }

    public function getCouponPoints($cid,$mn_sid,$otherCondition=[])
    {
        ini_set('serialize_precision',"14");
//        if(empty($otherCondition['mid'])){
//            return Normal::returnCode(Normal::FAIL, '请先登录');
//        }
        if(empty($otherCondition['mid'])){
            $member['mid']=0;
            $member['is_vip']=0;
            $member['goods_points']=0;
            $member['parent_id']=0;
        }else{
            $member=Member::instance()->info(['mid'=>$otherCondition['mid']]);
            $member['is_vip']=0;
            if($member['vip_level']>0 && $member['vip_expired']>time()){
                $member['is_vip']=1;
            }
        }

//        $is_vip=$member['is_vip'];
        $mn_user=Mnuser::instance()->info(['id'=>$mn_sid]);
        $goodsList=$otherCondition['goods_list'];
        $sendGoods=empty($otherCondition['send_goods'])?[]:$otherCondition['send_goods'];
        $bonded_num=0;//保税商品数量
        $goods_ids=array_column($goodsList,'goods_id');
        $activityList       = ActivityStoreService::instance()->getStoreActivity($cid, $mn_sid, (int)$otherCondition['mid'], $mn_user,$goods_ids, $member);
        $activityListMap    = array_column($activityList,null,'goods_id');
        $price_fullReduction=0;//满减总优惠
        $price_goods_reduction=0;//商品活动总优惠
        $price_discount=0;//特价总优惠
        $fullActivityArea=[];
        $goodsActivityArea=[];
        $allSendGoods=[];
        $activityGroup =[];//商品列表;
        $fullOrderActivity=[];
        foreach ($goodsList as $k=>$v){
            $info                               = Goods::instance()->info(['id' => $v['goods_id']]);
            $goodsList[$k]['use_points']        = $info['use_points'];
            $goodsList[$k]['can_return_points'] = $info['return_points'];
            $goodsList[$k]['tax_rate']          = $info['tax_rate'];
            $goodsList[$k]['high_tax_rate']     = $info['high_tax_rate'];
            $goodsList[$k]['high_price']        = $info['high_price'];
            $goodsList[$k]['price_coupon']      = 0;
//            $goodsList[$k]['specialActivityDiscount']=0;//特价
//            $goodsList[$k]['orderActivityDiscount']=0;//拼团秒杀优惠
            $goodsList[$k]['price_full_reduction']    = 0;//整单
            $goodsList[$k]['price_goods_reduction']   = 0;//满减
            $goodsList[$k]['price_tax']               = 0;
            $goodsList[$k]['return_points']           = 0;
            $goodsList[$k]['return_invite_points']    = 0;
            $goodsList[$k]['is_high']                 = 0;
            $goodsList[$k]['is_combine_goods']        = $info['is_combine_goods'];
            $goodsList[$k]['combine_goods_json_body'] = $info['combine_goods_json_body'];
            //商品促销
            $activity = $activityListMap[$v['goods_id']] ?? [
                'fullActivity'      => null,
                'fullActivityInfo'  => null,
                'goodsActivity'     => null,
                'bookActivity'      => null,
                'seckillActivity'   => null,
                'detailTag'         => null,
                'listTag'           => null,
                'fullTag'           => '',
                'sendActivity'      => 0,
            ];
            $fullActivityInfo=$activity['fullActivityInfo'];
            if($fullActivityInfo){
                $fullOrderActivity['activity_id']=$fullActivityInfo['id'];
                $fullOrderActivity['name']=$fullActivityInfo['name'];
                $fullOrderActivity['rule']=$activity['fullTag'];
            }
            $fullActivity=$activity['fullActivity'];
            $goodsActivity=$activity['goodsActivity'];
            $goodsList[$k]['isSpecialActivity']=0;
            if($fullActivity){
                $goodsList[$k]['isFullActivity']=1;
            }else{
                $goodsList[$k]['isFullActivity']=0;
            }
            $goodsList[$k]['activity_id']=0;
            //判断是否有商品促销活动
            if(empty($goodsActivity)){
                $goodsList[$k]['isGoodsActivity']=0;
                //没有商品促销
                if(!empty($fullActivity)){
                    //加入整单优惠计算池
                    $calculate['money']=$goodsList[$k]['price'];
                    $calculate['num']=$v['buy_num'];
                    $calculate['goods_id']=$v['goods_id'];
                    $fullActivityArea[]=$calculate;
                }
            }else{
                //有商品促销
                $goodsList[$k]['isGoodsActivity']=1;
                $calculate['money']=$goodsList[$k]['price'];
                $calculate['num']=$v['buy_num'];
                $calculate['goods_id']=$v['goods_id'];
                $goodsList[$k]['activity_id']=$goodsActivity['id'];
                $goodsActivityArea[$goodsActivity['id']][]=$calculate;
                $activityGroup[$goodsActivity['id']]['activity']=[];
                $activityGroup[$goodsActivity['id']]['activity']['id']=$goodsActivity['id'];
                $activityGroup[$goodsActivity['id']]['activity']['rule']=$activity['goodsTag'];
            }
            if($info['is_bonded']==1){
                $bonded_num+=1;
            }
        }
        $price=$otherCondition['price'];
        $goodsList=array_column($goodsList,null,'goods_id');
        //开始计算活动 ╭∩╮（︶︿︶）╭∩╮
        if(!empty($goodsActivityArea)){
            foreach ($goodsActivityArea as $k=>$v){
                $money=array_sum(array_column($v,'money'));
                $num=array_sum(array_column($v,'num'));
                $activity_result=ActivityStoreService::instance()->getTotalPrice(['activity_id'=>$k,'money'=>$money,'num'=>$num,'mn_sid'=>$mn_sid,'source'=>'cart']);
                $dropPrice=$activity_result['data']['drop_price'];
                $is_full=$activity_result['data']['is_full'];
                if($dropPrice>0){
                    $price_goods_reduction+=$dropPrice;
                }
                $goodsActSendGoods=$activity_result['data']['send_goods'];
                $activityGroup[$k]['activity']['desc']=$activity_result['data']['dec'];
                $activityGroup[$k]['activity']['tag']=$activity_result['data']['tag'];
                $activityGroup[$k]['activity']['send_goods']=$goodsActSendGoods;//可选赠品
                $activityGroup[$k]['activity']['send_num']=$activity_result['data']['send_num'];//可选赠品数量
                if(!empty($allSendGoods)){
                    $allSendGoods=array_merge($allSendGoods,$goodsActSendGoods);
                }else{
                    $allSendGoods=$goodsActSendGoods;
                }
                if(!empty($goodsActSendGoods)){
                    $sendNum=0;
                    $check_id=array_column($goodsActSendGoods,'id');
                    //判断选择的赠送商品，是否是可选的赠送商品
                    foreach ($sendGoods as $key=>$value){
                        if(in_array($value['id'],$check_id) && $value['activity_id']==$k){
                            $sendNum+=$value['buy_num'];
                        }
                    }
                    if($sendNum>$activity_result['data']['send_num']){
                        return Normal::returnCode(Normal::FAIL, '赠品数量超出活动限制');
                    }
                }
                //计算每个商品的实际单价
                $activityGoodsNum=count($v);
                $plusMoney=0;
                foreach ($v as $key => $value){
                    if($key < $activityGoodsNum-1){
                        $reduceMoney=round($value['money']/$money*$dropPrice,2);
                        $plusMoney+=$reduceMoney;
                    }else{
                        $reduceMoney=round($dropPrice-$plusMoney,2);
                    }
                    $old_price_pay=$goodsList[$value['goods_id']]['price'];
                    $new_price_pay=round($old_price_pay-$reduceMoney,2);
                    $goodsList[$value['goods_id']]['price']=$new_price_pay;
                    //实际支付单价，为了避免四舍五入造成商品单价乘以数量比实际支付价格少，导致订单申报失败，此处小数点第三位进一，多出的价格申报的时候算作折扣
                    $goodsList[$value['goods_id']]['price_goods_reduction']=$reduceMoney;
                    $goodsList[$value['goods_id']]['activity_id']=$k;
                    //检查是否有整单促销叠加商品活动促销
                    if(!empty($fullActivityInfo) && (in_array($fullActivityInfo['act_super'],[2,3]) || $is_full==0)){
                        //显示特价叠加整单优惠
                        $calculateGoodsActivity['money']=$new_price_pay;
                        $calculateGoodsActivity['num']=$goodsList[$value['goods_id']]['buy_num'];
                        $calculateGoodsActivity['goods_id']=$value['goods_id'];
                        $fullActivityArea[]=$calculateGoodsActivity;
                    }
                }
            }
        }
        if(!empty($fullActivityArea) && !empty($fullActivityInfo)){
            $money=array_sum(array_column($fullActivityArea,'money'));
            $num=array_sum(array_column($fullActivityArea,'num'));
            $activity_result=ActivityStoreService::instance()->getTotalPrice(['activity_id'=>$fullActivityInfo['id'],'money'=>$money,'num'=>$num,'mn_sid'=>$mn_sid,'source'=>'cart']);
            $fullActivityId=$fullActivityInfo['id'];
            $price_fullReduction=$activity_result['data']['drop_price'];
            $sendGoodsNum=$activity_result['data']['send_num'];
            $sendFullGoods=$activity_result['data']['send_goods'];//可选赠送商品
            $fullOrderActivity['tag']='整单促销';
            $fullOrderActivity['desc']=$activity_result['data']['dec'];
            $fullOrderActivity['send_goods']=$sendFullGoods;
            $fullOrderActivity['send_num']=$sendGoodsNum;
            if(!empty($allSendGoods)){
                if(!empty($sendFullGoods)){
                    $allSendGoods=array_merge($allSendGoods,$sendFullGoods);
                }
            }else{
                $allSendGoods=$sendFullGoods;
            }
            if(!empty($sendGoods) && !empty($sendFullGoods)){
                $sendNum=0;
                $check_id=array_column($sendFullGoods,'id');
                //判断选择的赠送商品，是否是可选的赠送商品
                foreach ($sendGoods as $key=>$value){
                    if(in_array($value['goods_id'],$check_id)){
                        $sendNum+=$value['buy_num'];
                    }
                }
                if($sendNum>$sendGoodsNum){
                    return Normal::returnCode(Normal::FAIL, '赠品数量超出活动限制');
                }
            }
            if($price_fullReduction>0){
                //计算实际单价
                //计算每个商品的实际单价
                $activityFullNum=count($fullActivityArea);
                $plusMoney=0;
                foreach ($fullActivityArea as $key => $value){
                    if($key < $activityFullNum-1){
                        $reduceMoney=round($value['money']/$money*$price_fullReduction,2);
                        $plusMoney+=$reduceMoney;
                    }else{
                        $reduceMoney=round($price_fullReduction-$plusMoney,2);
                    }
                    $old_price_pay=$goodsList[$value['goods_id']]['price'];
                    $new_price_pay=round($old_price_pay-$reduceMoney,2);
                    $goodsList[$value['goods_id']]['price']=$new_price_pay;
                    $goodsList[$value['goods_id']]['price_full_reduction']=$reduceMoney;
                }

            }
        }
        if(!empty($sendGoods)){
            if(empty($allSendGoods)){
                return Normal::returnCode(Normal::FAIL, '没有活动可以选择赠品');
            }
            $check_id=array_column($allSendGoods,'id');
            foreach ($sendGoods as $k=>$v){
                if(!in_array($v['goods_id'],$check_id)){
                    return Normal::returnCode(Normal::FAIL, '商品:'.$v['name'].'不是赠送商品');
                }
            }
        }
        $price = round($price - $price_fullReduction-$price_goods_reduction, 2);
        $canUseCoupon=[];
        $noUseCoupon=[];
        $mostValue=[];
        $couponDiscount=0;
        $coupon=CouponService::instance()->getAbleCoupon($cid,$mn_sid,['mid'=>$otherCondition['mid']]);
        $allCoupon=$coupon['data'];
        $allCoupon=array_column($allCoupon,null,'coupon_id');
        if($allCoupon){
            foreach ($allCoupon as $couponKey => $couponValue){
                $couponGoodsIds=[];
                if($couponValue['status']==1){
                    continue;
                }
                foreach ($goodsList as $goodsKey => $goodsValue){
//                    if($goodsValue['is_send']==1){
//                        continue;
//                    }
                    //优惠券指定商品或者类型
                    if($couponValue['type']==2 && !in_array($goodsKey,explode(',',$couponValue['type_value']))){
                        continue;
                    }
                    //改价商品不参与优惠券
                    if($goodsValue['is_modify_price']==1){
                        continue;
                    }
                    //活动叠加
                    if(
                        ($couponValue['addition']==1 && ($goodsValue['isFullActivity']==1 || $goodsValue['isGoodsActivity']==1)) ||
                        ($couponValue['addition']==2 && $goodsValue['isGoodsActivity']==1) ||
                        ($couponValue['addition']==3 && $goodsValue['isFullActivity']==1)
                    ){
                        continue;
                    }
                    $allCoupon[$couponKey]['money']+=$goodsValue['price'];
                    $couponGoodsIds[]=$goodsValue['goods_id'];

//                    $price += $goodsList[$goodsKey]['price'];
                }
                if($allCoupon[$couponKey]['money']>0 && $allCoupon[$couponKey]['money']>=$couponValue['min_amount']){
                    $canUseCoupon[$couponKey]=$couponValue;
                    $canUseCoupon[$couponKey]['goods_id']=$couponGoodsIds;
                    if(empty($mostValue)){
                        $mostValue=$allCoupon[$couponKey];
                    }else{
                        if($couponValue['sub_amount']>$mostValue['sub_amount']){
                            $mostValue=$allCoupon[$couponKey];
                        }
                    }
                    unset($allCoupon[$couponKey]);//可用的优惠券去掉，剩下不可用
                }
            }
        }

        $noUseCoupon=!empty($allCoupon) ? array_values($allCoupon):[];
        if($canUseCoupon){
            if(isset($otherCondition['coupon_id']) && $otherCondition['coupon_id']>0){
                if(isset($canUseCoupon[$otherCondition['coupon_id']])){
                    $canUseCoupon[$otherCondition['coupon_id']]['is_default']=1;
                    $useCouponGoods=$canUseCoupon[$otherCondition['coupon_id']]['goods_id'];
                    $mostValue=$canUseCoupon[$otherCondition['coupon_id']];
                    $couponDiscount=$mostValue['sub_amount'];
                    $price-=$mostValue['sub_amount'];
                }else{
                    return [
                        'code' => Normal::FAIL,
                        'msg' => '选择的优惠券没有达到使用条件',
                    ];
                }
            }else{
                if($otherCondition['is_order']==0 && !isset($otherCondition['coupon_id'])){
                    //下单时没传优惠券则不扣除优惠券
                    $canUseCoupon[$mostValue['coupon_id']]['is_default']=1;
                    $useCouponGoods=$canUseCoupon[$mostValue['coupon_id']]['goods_id'];
                    $couponDiscount=$mostValue['sub_amount'];
                    $price = bcsub((string)$price,(string)$mostValue['sub_amount'],2);
                }
            }
            $canUseCoupon=array_values($canUseCoupon);
        }
        $goodsList = array_values($goodsList);
        if($couponDiscount>0){
            //平摊优惠券折扣
            $goodsList=CouponService::instance()->averageCoupon(['goods'=>$goodsList,'coupon_pay'=>$couponDiscount,'useCouponGoods'=>$useCouponGoods]);
        }
        $show_points=0;//是否显示积分板块
        $goods_points['is_show_return']=0;//是否显示购物返积分
        $goods_points['is_show_use']=0;//是否显示积分抵扣
        $goods_points['points_money']=0;//可抵扣的金额
        $goods_points['member_points']=round($member['goods_points'],2);//用户可用积分
        $return_points=0;//预计返积分
        $return_invite_points=0;//预计邀请者返积分
        $goodsPointsInfo=GoodsPointsConfig::instance()->info(['cid'=>$cid]);
        if(!empty($goodsPointsInfo) && $goodsPointsInfo['store_status']==1){
            $show_points=1;
            if($goodsPointsInfo['return_points_store_status']==1){
                $goods_points['is_show_return']=1;
            }
            if($goodsPointsInfo['points_use_store_status']==1){
                $goods_points['is_show_use']=1;
                $goods_points['return_points_rule']=$goodsPointsInfo['content'];
            }
            $goods_points['points_ratio']=$goodsPointsInfo['points_ratio'];
        }
        $tax=0;//税费
        foreach ($goodsList as $k=>$v){
            if(!empty($goodsPointsInfo)){

                if( $goods_points['is_show_return']==1){
                    if(($goodsPointsInfo['return_points_goods']==1 || ($goodsPointsInfo['return_points_goods']==2 && $v['can_return_points']==1))){
                        if($goodsPointsInfo['return_points_type']==0){
                            //返积分相关,类型为商品数量
                            $goodsList[$k]['return_points']=$v['num']*$goodsPointsInfo['return_points'];
                            $return_points+=$goodsList[$k]['return_points'];
                        }elseif($goodsPointsInfo['return_points_type']==1){
                            //返积分相关,类型为商品价格
                            if($goodsPointsInfo['return_base_money']>0 && $v['price']>0){
                                $base_money=floor($v['price']/$goodsPointsInfo['return_base_money']);
                                $goodsList[$k]['return_points']=$base_money*$goodsPointsInfo['return_points'];
                                $return_points+=$goodsList[$k]['return_points'];
                            }
                        }else{
                            //返积分相关,类型为下单金额
                            if($goodsPointsInfo['store_return_ratio']>0 && $v['price']>0){
                                $goodsList[$k]['return_points']=$v['price']*$goodsPointsInfo['store_return_ratio'];
                                $return_points+=$goodsList[$k]['return_points'];
                            }
                            if($member['parent_id']>0 && $goodsPointsInfo['store_return_invite']==1 && $goodsPointsInfo['store_return_invite_ratio']>0 && $v['price']>0){
                                $goodsList[$k]['return_invite_points']=$v['price']*$goodsPointsInfo['store_return_invite_ratio'];
                                $return_invite_points+=$goodsList[$k]['return_invite_points'];
                            }
                        }
                    }
                }
                if($goods_points['is_show_use']==1){
                    //计算可用积分抵扣的金额
                    if($goodsPointsInfo['points_use_goods']==1 || ($goodsPointsInfo['points_use_goods']==2 && $v['use_points']==1)){
                        $goods_points['points_money']+=$v['price'];
                    }
                }
                //反算税费
                if ($goodsList[$k]['is_combine_goods'] == 1) { //组合装商品
                    $single_goods              = $v;
                    $single_goods['price_pay'] = $v['price'];

                    $combine_goods = $this->combineGoodsTaxFee($cid, $single_goods);

                    $goodsList[$k]['is_high']                    = $combine_goods['is_high'];

                    $goodsList[$k]['price_tax']                  = $combine_goods['price_total_tax'];//单商品销售税金

                    $goodsList[$k]['tax_rate']                   = $combine_goods['tax_rate']; //新税率

                    $goodsList[$k]['price_pay']                  = $combine_goods['price_pay'];//单个销售不含税价

                    $goodsList[$k]['price']                      = $combine_goods['price_pay'];//销售不含税价

                    $goodsList[$k]['store_total_tax']            = $combine_goods['store_total_tax'];//店铺税金

                    $goodsList[$k]['channel_total_tax']          = $combine_goods['channel_total_tax'];//渠道税金

                    $goodsList[$k]['price_store_no_tax']         = $combine_goods['price_store_no_tax'];//店铺不含税价

                    $goodsList[$k]['store_store_total_tax']      = $combine_goods['store_store_total_tax'];//店铺成本不含税价

                    $goodsList[$k]['store_store_cost_total_tax'] = $combine_goods['store_store_cost_total_tax'];//店铺成本税金

                    $goodsList[$k]['combine_goods_json_body']    = $combine_goods['combine_goods_json_body'];

                } else {
                    $goodsList[$k]['is_high'] = 0;
                    $tax_rate                 = $v['tax_rate'];
                    $price_pay                = round($v['price'] / $v['num'], 2);
                    if ($v['high_price'] > 0 && $price_pay >= $v['high_price']) {
                        $goodsList[$k]['is_high'] = 1;//判断是否触发高税率
                        $tax_rate                 = $v['high_tax_rate'];
                    }
                    $goodsList[$k]['tax_rate']  = $tax_rate;
                    $newPrice                   = round($price_pay / (1 + $tax_rate), 2);
                    $goodsList[$k]['price']     = $newPrice;
                    $goodsList[$k]['price_tax'] = round($price_pay - $newPrice, 2);
                    $goodsList[$k]['price_pay'] = $newPrice;
                }

                $single_goods_tax = $goodsList[$k]['price_tax'] * $v['num'];

                $tax = round($tax + $single_goods_tax,2);

            }
        }
        if($return_points>0 && $member['mid']>0){
            //查看是否有积分获取上限
            $begin_time=strtotime(date('Y-m-d',time()));
            $return_goods_points=Db::table('ly_order')
                ->where([
                    ['mid','=',$member['mid']],
                    ['status','>',0],
                    ['cd','>=',$begin_time],
                ])->sum('return_goods_points');
            if($goodsPointsInfo['points_limit_status']==1){
                //开启了获取上限
                $left_return=$goodsPointsInfo['points_limit']-$return_goods_points;
                if($left_return<=$return_points){
                    $return_points=$left_return<0?0:$left_return;
                }
            }
        }

        //计算支付总价
        $payment_price = 0;
        foreach ($goodsList as $v){
            $payment_price += $v['price'] * $v['num'];
        }
//        $payment_price = $goods_points['points_money'] = $payment_price + $tax;

        $goods_points['return_points']        = round($return_points, 2);
        $goods_points['return_invite_points'] = round($return_invite_points, 2);
        $goods_points['limit_lowest']         = 1;//是否达到积分抵扣的最低门槛 1-达到 0-未达到
        $goods_points['points_use']           = 0;//可使用积分
        $goods_points['instead_money']        = 0;//抵扣金额
        $goods_points['bonded_order_floor']   = 0;//保税订单总底价
        $goods_points['bonded_order_money']   = 0;
        $goods_points['points_money']         = (string)round($goods_points['points_money'], 2);
        $points_price                         = $goods_points['points_money'];
        if($goods_points['points_money']>0){
            //扣除保税商品最低支付价格
            $minPay=0;
            if($bonded_num>0){
                $minPay=$goodsPointsInfo['bonded_order_money'];
            }
            $goods_points['bonded_order_money']=$goodsPointsInfo['bonded_order_money'];
            $goods_points['bonded_order_floor']=$minPay;
            if($goodsPointsInfo['points_min_type']==2 && $goods_points['points_money']<$goodsPointsInfo['points_min_money']){
                //没有达到订单最低金额
                $goods_points['points_money']=0;
                $goods_points['points_use']=0;
                $goods_points['limit_lowest']=0;
                $goods_points['lowest_money']=round($goodsPointsInfo['points_min_money'],2);
            }else{
                //抵扣上限
                $maxPay=0;
                if($goodsPointsInfo['points_max_type']==2){
                    //配置未订单做多抵扣金额
                    $maxPay=round($goodsPointsInfo['points_max_money'],2);
                }
                if($goodsPointsInfo['points_max_type']==3){
                    //配置未订单做多抵扣百分比
                    $maxPay=round($goods_points['points_money']*$goodsPointsInfo['points_max_rate']/100,2);
                }
                if($goods_points['points_money']>$maxPay && $maxPay>0){
                    $goods_points['points_money']=$maxPay;
                }
                if($minPay>0 && $goods_points['points_money']>$points_price-$minPay){
                    $goods_points['points_money']=(string)round($points_price-$minPay,2);
                }
                $goods_points['points_use']=(string)round($goods_points['points_money']*$goodsPointsInfo['points_ratio'],2);
            }
        }
        $otherCondition['goods_points']=$otherCondition['goods_points']??0;

        //积分判断
        if($otherCondition['goods_points']>0){
            if($otherCondition['goods_points']>$member['goods_points']){
                return [
                    'code' => Normal::FAIL,
                    'msg' => "可使用积分不足，当前可用积分".round($member['goods_points'],2),
                ];
            }
            if($otherCondition['goods_points']>$goods_points['points_use']){
                return [
                    'code' => Normal::FAIL,
                    'msg' => "超过本次下单积分使用上限，本次最多使用积分".$goods_points['points_use'],
                ];
            }
            $goods_points['instead_money']=round($otherCondition['goods_points']/$goodsPointsInfo['points_ratio'],2);
            $goods_points['use_points']=$otherCondition['goods_points'];
            $price=bcsub((string)$price,(string)$goods_points['instead_money'],2);
            $payment_price = bcsub((string)$payment_price,(string)$goods_points['instead_money'],2);
        }


        $totalDiscount=round($price_discount+$price_fullReduction+$price_goods_reduction+$couponDiscount,2);
        $cartList=[];
        $i=0;
        //商品按活动分组
        foreach ($activityGroup as $k=>$v){
            $cartList[$i]['activityInfo']=$v['activity'];
            $cartList[$i]['goodsList']=[];
            foreach ($goodsList as $key=>$item){
                if($item['activity_id']==$k){
                    $cartList[$i]['goodsList'][]=$item;
                    unset($goodsList[$key]);
                }
            }
            $i++;
        }
        if(!empty($goodsList)){
            $goodsList=array_values($goodsList);
        }
        return [
            'code' => Normal::SUC,
            'msg' => '获取成功',
            'data' => [
                'goods'                   => $goodsList,//所有商品
                'activityGoods'           => $cartList,//活动分组商品
                'fullOrderActivity'       => $fullOrderActivity,//整单促销活动
                'price'                   => (string)$price,//商品支付总价
                'tax'                     => (string)$tax,//商品总税费
                'couponDiscount'          => (string)$couponDiscount,//优惠券优惠金额
                'priceFullReduction'      =>  (string)round($price_fullReduction,2),//整单促销满减总优惠
                'priceGoodsReduction'     =>  (string)round($price_goods_reduction,2),//商品促销满减总优惠
                'totalDiscount'           =>  (string)round($totalDiscount,2),//总优惠
                'canUseCoupon'            => $canUseCoupon,//可用优惠券
                'noUseCoupon'             => $noUseCoupon,//不可用优惠券
                'show_points'             => $show_points,//是否显示积分板块
                'goods_points'            => $goods_points,//积分相关
            ],
        ];

    }

    /**
     * 组合装商品税率处理
     * @param int $cid
     * @param array $good price_pay
     * @return array
     */
    public function combineGoodsTaxFee(int $cid,array $good,$is_goods_list = 0){

        $combine_goods_json_body = json_decode($good['combine_goods_json_body'] , true);

        $skucodeMap = array_column($combine_goods_json_body,'SkuCode');

        //渠道每个商品标准税率 skucode=>tax_rate
        $skucodeMapGoodsResult = Goods::instance()
            ->where(['cid' => $cid,'df'=> 0])
            ->whereIn('skucode',$skucodeMap)
            ->select('tax_rate','price_cost','high_price','high_tax_rate','skucode')
            ->get()
            ->toArray();
        $skucodeMapGoods = array_column($skucodeMapGoodsResult,null,'skucode');

        //是否高税 0-否，1-是
        $is_high = 0;

        //含税消费价
        if($is_goods_list == 1){
            $good['num'] = 1;
        }
        $price_pay      = $good['price_pay'] / $good['num'];
        $goods_info     = Goods::instance()
            ->where(['id' => $good['goods_id']])
            ->select(['price_cost','price_store'])
            ->first();
        $price_cost = $goods_info['price_cost'];
        $price_store = $goods_info['price_store'];
        //店铺总税费
        $price_total_tax = $store_total_tax = $channel_total_tax = $store_store_total_tax = 0;
        foreach ($combine_goods_json_body as &$combine_good)
        {

            $combine_good['price_pay']              = $price_pay;
            $combine_good['ly_goods_tax_rate']      = $skucodeMapGoods[$combine_good['SkuCode']]['tax_rate'] ?? 0;
            $combine_good['ly_goods_high_price']    = $skucodeMapGoods[$combine_good['SkuCode']]['high_price'] ?? 0;
            $combine_good['ly_goods_high_tax_rate'] = $skucodeMapGoods[$combine_good['SkuCode']]['high_tax_rate'] ?? 0;

            //销售税金
            $price_total_tax = bcadd((string)$price_total_tax,(string)$this->getTaxFee($price_pay,$combine_good,$skucodeMapGoods,3)['singlePriceTax'],2);
            if($this->getTaxFee($price_pay,$combine_good,$skucodeMapGoods,3)['is_high'] > 0){
                $is_high++;
            }
            $combine_good['tax_rate'] = $this->getTaxFee($price_pay,$combine_good,$skucodeMapGoods,3)['tax_rate'];
            //店铺税金 (售价*比例/(1+税率)*税率)
            $store_total_tax = bcadd((string)$store_total_tax,(string)$this->getTaxFee($price_pay,$combine_good,$skucodeMapGoods,2)['singlePriceTax'],2);

            //渠道成本税金 (成本*比例/(1+税率)*税率)
            $channel_total_tax = bcadd((string)$channel_total_tax,(string)$this->getTaxFee($price_cost,$combine_good,$skucodeMapGoods,1)['singlePriceTax'],2);

            //店铺成本税金
            $store_store_total_tax = round($store_store_total_tax + $this->getTaxFee($price_store,$combine_good,$skucodeMapGoods,1)['singlePriceTax'],2);

            $combine_good['price_total_tax']      = $price_total_tax;
            $combine_good['channel_total_tax']    = $channel_total_tax;
            $combine_good['store_cost_total_tax'] = $store_store_total_tax;
            $combine_good['tax_rate']             = $this->getTaxFee($price_pay, $combine_good, $skucodeMapGoods, 3)['tax_rate'];
        }

        //新的税率
        $new_rate = bcdiv((string)$price_total_tax , (string)$price_pay,4);
        if($is_high > 0){
            $is_high = 1;
        }
        return [
            'tax_rate'                   => $new_rate,
            'is_high'                    => $is_high,
            'price_total_tax'            => $price_total_tax,//销售税金
            'store_total_tax'            => $store_total_tax,//店铺税金
            'channel_total_tax'          => $channel_total_tax,//渠道税金
            'store_store_cost_total_tax' => $store_store_total_tax,//店铺的成本税金
            'price_pay'                  => bcsub((string)$price_pay, (string)$price_total_tax, 2),//销售不含税价
            'price_store_no_tax'         => bcsub((string)$price_pay, (string)$store_total_tax, 2),//店铺不含税价
            'price_channel_no_tax'       => bcsub((string)$price_cost, (string)$channel_total_tax, 2),//渠道不含税价
            'store_store_total_tax'      => bcsub((string)$price_store, (string)$store_store_total_tax, 2),//店铺成本不含税价
            'combine_goods_json_body'    => json_encode($combine_goods_json_body),
        ];
    }

    /**
     * 计算单个子商品的税金
     * @param $price //不含税价格
     * @param $combine_good //子商品基础数据
     * @param $skucodeMapGoods //子商品的税率
     * @param $type //1-渠道，2-店铺，3-小C
     * @return array
     */
    public function getTaxFee($price,$combine_good,$skucodeMapGoods,$type)
    {
        $is_high = 0;
        //单个商品含税价格-组合装占比的含税价格
        $single_good_price = $price * $combine_good['GoodsScale'] / 100;

        $GoodsPackageNum = $combine_good['GoodsPackageNum'];

        //单个商品单规格含税单价
        $single_spec_price = round($single_good_price / $GoodsPackageNum,2);

        if(!$combine_good['ConSumptionTaxRate'] || !$combine_good['ConSumptionPrice']){ //不处理高消费税

            $tax_rate = $skucodeMapGoods[$combine_good['SkuCode']]['tax_rate'] ?? 0;

            $singlePriceTax = round($single_spec_price / ( 1 + $tax_rate) * $tax_rate,2);
            $singlePriceTax = $singlePriceTax * $GoodsPackageNum;
        }else{

            //不含税的单商品单规格价格
            $single_spec_no_tax_price = round($single_spec_price / (1 + $combine_good['ly_goods_tax_rate']),2);

            //预警价
            $ConSumptionPrice = $combine_good['ConSumptionPrice'];

            //高消费税
            $ConSumptionTaxRate = $combine_good['ConSumptionTaxRate'] / 100;


            if($single_spec_no_tax_price >= $ConSumptionPrice){ //触发高税率
                if($type == 3){
                    $is_high++;
                }
                $tax_rate = $ConSumptionTaxRate;
            }else{
                $tax_rate = $skucodeMapGoods[$combine_good['SkuCode']]['tax_rate'] ?? 0;
            }

            //新的不含税价格
            $new_single_spec_no_tax_price = round($single_spec_price / (1 + $tax_rate),2);

            //单个商品的税费
            $singleSpecTax              = bcsub((string)$single_spec_price, (string)$new_single_spec_no_tax_price,4);
            $singlePriceTax             = bcmul((string)$singleSpecTax,(string)$GoodsPackageNum,4);//单商品的税费
        }

        return [
            'singlePriceTax' => round($singlePriceTax,2),
            'is_high' => $is_high,
            'tax_rate' => $tax_rate,
        ];

    }

    /**
     * 获取组合装商品的税费
     * @param $cid
     * @param $param
     * @return array
     */
    public function getCombineGoodsTaxFee($cid,$param){
        $price_pay = $param['new_price_pay'];

        $goods = Goods::instance()
            ->where(['cid' => $cid,'id' => $param['goods_id']])
            ->select(['id as goods_id','tax_rate','high_price','high_tax_rate','is_combine_goods','combine_goods_json_body'])
            ->first()->toArray();
        if($goods['is_combine_goods'] == 1){ //组合装商品
            $goods['price_pay'] = $price_pay;
            $goods['num'] = 1;
            $price_total_tax = $this->combineGoodsTaxFee($cid,$goods)['price_total_tax'] ?? 0;
        }else{
            $price_total_tax = (new CashGoodsService())->singGoodsPriceFree($price_pay,$goods);
        }

        return Normal::returnCode(Normal::SUC, '成功',$price_total_tax);
    }


    /**
     * 订单按照仓库，商品类型分组
     * @param $goods
     * @return array
     */
    public function orderGroup($goods){

        usort($goods, function($a, $b) {
            return $a['is_bonded'] - $b['is_bonded'];
        });

        //按仓库分组
        $supplierGoods = [];
        foreach ($goods as $val){
            $supplierGoods[$val['supplier_id']][] = $val;
        }

        //按商品类型分组
        $is_bondedGoods = [];
        foreach ($supplierGoods as $key=>$val){
            foreach ($val as $v){
                $is_bondedGoods[$key][$v['is_bonded']][] = $v;
            }
        }

        //判断是否可以合并下单
        //$key => 仓库ID  $k=>商品类型
        foreach ($is_bondedGoods as $key=>$val){
            foreach ($val as $k=>$v){
                foreach ($v as $gk=>$gv){
                    if($gv['store_isCombineOrders'] == 0){ //不可以合并下单
                        unset($is_bondedGoods[$key][$k][$gk]);
                        $is_bondedGoods[$key][-1][] = $gv;
                    }
                }
            }
        }

        $newGoods = [];
        foreach ($is_bondedGoods as $val){
            foreach ($val as $v){
                if($v){
                    $newGoods[] = $v;
                }
            }
        }

        return $newGoods;
    }

    /**
     * 创建订单
     * @param $cid
     * @param $body //经理过商品价格处理的数据
     * @param $goods //已经组装可以合并下单的商品组装成二维数组
     * @param $mn_sid
     * @param $mid
     * @param $client
     * @param $cash_register_id
     * @param $manager_id
     * @param $time
     * @return array
     */
    public function createOrder($cid,$body,$goods,$mn_sid,$mid,$client,$cash_register_id,$manager_id,$time,$storeProfitType = 1){

        $mn_user = $body['mn_user'];

        //收货地址
        $receive_info = isset($body['address']) ? json_encode($body['address'],JSON_UNESCAPED_UNICODE):json_encode([]);

        //支付手续费
        $pay_fee_config = ChannelConfigService::instance()->getChannelConfig('pay_fee', $cid);
        $pay_fee        = ChannelConfigService::instance()->getPayFee((string)($pay_fee_config['fee'] ?? '0'));

        //获取店铺支付配置,统一走店铺支付
        $storePayConfig = StoreConfigService::instance()->getConfig('pay_way', $mn_sid);
        $scan_rece_type = (int)($storePayConfig['type'] ?? 0);

        //获取导购员ID
        $guide_id = 0;
        if($mid){
            $member_info= MemberInfo::instance()->info(['mid'=>$mid]);
            if($member_info['guide_now']){
                $guide_id = $member_info['guide_now'];
            }
        }

        $pay_sn = $this->getBuilderSn($mn_sid);


        //使用积分
        $has_div_points = 0;
        //积分抵扣金额
        $has_div_points_money = 0;
        //抹零
        $has_div_giveup_money = 0;
        //现金
        $has_div_cash = 0;
        //扫码付款
        $has_div_scan_pay = 0;
        //扫码收款
        $has_div_scan_rece = 0;
        //POS
        $has_div_pos = 0;
        //储值卡
        $has_div_storecard = 0;
        //整单优惠
        $has_div_total_fullReduction = 0;

        //运单申报数据，云仓订单推送数据
        $pushYunCangOrderData = [];

        //是否拆单，0-否；
        $is_combination_order = 0;

        foreach ($goods as $key => &$v){

            $orderAttr = [];

            if($v[0]['is_bonded'] == 1 && $v[0]['is_trade'] == 0){ //保税
                $order_type = 4;
            }else{ //一般贸易商品订单
                $order_type = 3;
            }
            $stoid = $v[0]['supplier_id'];

            if(count($goods) > 1){
                $order_sn  = $this->getBuilderSn($mn_sid);
                $is_combination_order = 1;
            }else{
                $order_sn  = $pay_sn;
            }

            //优惠券优惠券金额
            $coupon_id = 0;
            $price_coupon = 0;
            //满减优惠券金额
            $total_goodsReduction = 0;
            //整单优惠
            $total_fullReduction = 0;

            //计算可返积分
            $goods_ids = array_column($v,'goods_id');
            foreach ($body['goods'] as $gv){
                if (in_array($gv['goods_id'], $goods_ids)) {
                    $return_goods_points_pram['orderGoods'][] = $gv;
                    $gv['total_price_total']                  = $gv['price_total'];
                    $gv['total_price_pay']                    = $gv['price_pay'] * $gv['num'];
                    $gv['total_price_cost']                   = $gv['price_cost'] * $gv['num'];
                    $gv['total_channel_cost']                 = $gv['channel_cost'];
                    $gv['total_price_tax']                    = $gv['price_tax'] * $gv['num'];
                    $gv['cost_rate']                          = round($gv['price_cost'] / (1 + $gv['tax_rate']), 2) * $gv['num'];
//                    $gv['price_vipDiscount']                  = $gv['price_vipDiscount'] * $gv['num'];

                    $price_coupon              += $gv['price_coupon'] ?? 0;
                    $coupon_id                 = $gv['coupon_id'] ?? 0;
                    $total_goodsReduction      += $gv['price_goods_reduction'] ?? 0;
                    $total_fullReduction       += $gv['price_fullReduction'] ?? 0;
                    $orderAttr[]               = $gv;
                }
            }

            foreach ($body['goodsListMap'] as $gv){
                if(in_array($gv['id'],$goods_ids)){
                    $return_goods_points_pram['goodsListMap'][] = $gv;
                }
            }
            $return_points_data = GoodsPointsService::instance()->dealReturnGoodsPoints($cid, $mid, $return_goods_points_pram);
            $return_goods_points      = $return_points_data['return_goods_points'];
            $return_parent_points     = $return_points_data['return_parent_points'];

            //计算订单参数
            $price_total          = array_sum(array_column($orderAttr, 'total_price_total'));
            $price_order          = array_sum(array_column($orderAttr, 'total_price_pay'));
            $total_cost           = array_sum(array_column($orderAttr, 'total_price_cost'));
            $total_channel_cost   = array_sum(array_column($orderAttr, 'total_channel_cost'));
            $goods_num            = array_sum(array_column($orderAttr, 'num'));
            $total_priceSpecial   = array_sum(array_column($orderAttr, 'total_priceSpecial')) ?? 0;
            $total_modifyDiscount = array_sum(array_column($orderAttr, 'total_modifyDiscount')) ?? 0;
            $tax_fee              = array_sum(array_column($orderAttr, 'total_price_tax')) ?? 0;
            $cost_rate            = array_sum(array_column($orderAttr, 'cost_rate')) ?? 0;
            $total_vipDiscount    = array_sum(array_column($orderAttr, 'price_vipDiscount')) ?? 0;


            $points                     = isset($body['points']) ? $body['points'] : 0;
            $coupon                     = isset($body['coupon']) ? $body['coupon'] : 0;
            $balance                    = isset($body['balance']) ? $body['balance'] : 0;
            $total_scan_rece            = isset($body['scan_rece']) ? $body['scan_rece'] : 0;
            $total_scan_pay             = isset($body['scan_pay']) ? $body['scan_pay'] : 0;
            $total_cash                 = isset($body['cash']) ? $body['cash'] : 0;
            $total_giveup_money         = isset($body['giveup_money']) ? $body['giveup_money'] : 0; //抹零
            $pay_way                    = $body['pay_way'];
            $total_store_card_money     = isset($body['storecard']) ? $body['storecard'] : 0;
            $storecard_id               = isset($body['storecard_id']) ? $body['storecard_id'] : 0;
            $total_use_points           = isset($body['use_points']) ? $body['use_points'] : 0; //使用积分
            $total_goods_points         = isset($body['goods_points']) ? $body['goods_points'] : 0; //积分抵扣金额
            $total_pos                  = isset($body['pos']) ? $body['pos'] : 0;
//            $total_total_fullReduction  = isset($body['total_fullReduction']) ? $body['total_fullReduction'] : 0;


            if($key == count($goods) - 1)//最后一次循环
            {
                $use_points           = $total_use_points - $has_div_points;
                $goods_points         = $total_goods_points - $has_div_points_money;
                $giveup_money         = $total_giveup_money - $has_div_giveup_money;
                $cash                 = $total_cash - $has_div_cash;
                $scan_pay             = $total_scan_pay - $has_div_scan_pay;
                $scan_rece            = $total_scan_rece - $has_div_scan_rece;
                $pos                  = $total_pos - $has_div_pos;
                $store_card_money     = $total_store_card_money - $has_div_storecard;

            }
            else
            {
                //拆单-每个子单的占比
                $ratio = ($price_order + $tax_fee) / $body['price_order'];

                $use_points           = round($ratio * $total_use_points, 2);

                $goods_points         = round($ratio * $total_goods_points, 2);
                $giveup_money         = round($ratio * $total_giveup_money, 2);
                $cash                 = round($ratio * $total_cash, 2);
                $scan_pay             = round($ratio * $total_scan_pay, 2);
                $scan_rece            = round($ratio * $total_scan_rece, 2);
                $pos                  = round($ratio * $total_pos, 2);
                $store_card_money     = round($ratio * $total_store_card_money, 2);
//                $total_fullReduction  = round($ratio * $total_total_fullReduction, 2);



                $has_div_points               = $has_div_points + $use_points;
                $has_div_points_money         = $has_div_points_money + $goods_points;
                $has_div_giveup_money         = $has_div_giveup_money + $giveup_money;
                $has_div_cash                 = $has_div_cash + $cash;
                $has_div_scan_pay             = $has_div_scan_pay + $scan_pay;
                $has_div_scan_rece            = $has_div_scan_rece + $scan_rece;
                $has_div_pos                  = $has_div_pos + $pos;
                $has_div_storecard            = $has_div_storecard + $store_card_money;

                $has_div_total_fullReduction  = $has_div_total_fullReduction + $total_fullReduction;

            }

            //总优惠金额，除了黑卡优惠和优惠券优惠的所有优惠
            $total_discount = $total_fullReduction + $total_goodsReduction + $total_priceSpecial;

            //订单数据
            //订单金额-price_order用支付金额加积分抵扣金额算
            $old_price_order = $price_order;
            $price_order = $scan_rece + $scan_pay + $pos + $store_card_money + $goods_points;
            if($price_order == 0 )
            {
                $price_order = $old_price_order;
            }
            $orderAddData = [
                'mid'                   => $mid,
                'sn'                    => $order_sn,
                'price_total'           => $price_total,
                'price_order'           => $price_order,
                'total_cost'            => $total_cost,
                'cost_rate'             => $cost_rate,
                'total_channel_cost'    => $total_channel_cost,
                'goods_num'             => $goods_num,
                'base_num'              => $goods_num,
                'total_fullReduction'   => $total_fullReduction,
                'total_goodsReduction'  => $total_goodsReduction,
                'total_priceSpecial'    => $total_priceSpecial,
                'total_vipDiscount'     => $total_vipDiscount,
                'total_discount'        => $total_discount,
                'total_modifyDiscount'  => $total_modifyDiscount,
                'full_activity_id'      => $body['full_activity_id'] ?? 0,
                'pay_type'              => 8,
                'pay_serial'            => '',
                'pay_time'              => $time,
                'pay_sn'                => $pay_sn,
                'pay_rate'              => $pay_fee,
                'receive_info'          => $receive_info,
                'status'                => 50,
                'cd'                    => $time,
                'md'                    => $time,
                'shipping_time'         => $time,
                'stoid'                 => $stoid,
                'receive_time'          => $time,
                'client'                => $client,
                'mn_sid'                => $mn_sid,
                'mnid'                  => 4,
                'cid'                   => $cid,
                'type'                  => $order_type,
                'pay_status'            => 1,
                'order_message'         => isset($body['order_message'])?$body['order_message']:'',
                'return_goods_points'   => $return_goods_points,
                'return_parent_points'  => $return_parent_points,
                'price_coupon'          => $price_coupon,
                'coupon_id'             => $coupon_id,
                'guide_id'              => $guide_id,
                'store_profit_include_points' => $storeProfitType,
            ];

            //保税模式
            if( $order_type == CashOrderVolidate::BONDED_ORDER_TYPE )
            {

                //统计订单价格
                $orderAddData['status']             = 20;
                $orderAddData['is_bonded']          = 1;
                $orderAddData['need_pay_report']    = 1;
                $orderAddData['is_stb']             = 1;
                $orderAddData['shipping_time']      = $time;
                $orderAddData['receive_time']       = 0;
                $orderAddData['push_success']       = 0;
                $orderAddData['pay_success']        = 0;
                $orderAddData['tax_fee']            = $tax_fee;
                $orderAddData['buyer_mobile']       = $body['buyer']['mobile'];
                $orderAddData['buyer_name']         = $body['buyer']['truename'];
                $orderAddData['buyer_idcard']       = $body['buyer']['idcard'];
                $orderAddData['receive_mobile']     = $body['address']?$body['address']['mobile']:'';
                $orderAddData['receive_name']       = $body['address']?$body['address']['true_name']:'';
                $orderAddData['receive_address']    = $body['address']?$body['address']['province']['name'].$body['address']['city']['name'].$body['address']['area']['name'].$body['address']['address']:'';

                $order_report_status_data = [
                    'cid'               => $cid,
                    'mn_sid'            => $mn_sid,
                    'sn'                => $order_sn,
                    'cd'                => $time,
                    'clear_time'        => $time,
                    'express_time'      => $time,
                    'pay_report_time'   => $time,
                    'md'                => $time
                ];
            }


            $orderAddData['use_points']   = $use_points;
            $orderAddData['points_money'] = $goods_points;

            //订单扩展
            $orderExtendsData = [
                'cd'                => $time,
                'cid'               => $cid,
                'mn_sid'            => $mn_sid,
                'giveup_money'      => $giveup_money,
                'pay_way'           => implode(',',$pay_way),
                'cash'              => $cash,
                'scan_pay'          => $scan_pay,
                'scan_rece'         => $scan_rece,//扫码收款
                'scan_rece_type'    => $scan_rece_type,
                'pos'               => $pos,
                'storecard'         => $store_card_money,
                'storecard_id'      => $storecard_id,
                'balance'           => $balance,
                'coupon'            => $coupon,
                'points'            => $points,
                'cashregister_id'   => $cash_register_id,
                'casher'            => $manager_id,
                'user_pay_type'     => 0,
                'goods_points'      => $goods_points,
                'cash_receive'      => $body['cash_receive']??0,
                'cash_reback'       => $body['cash_reback']??0
            ];
            $orderExtendsData['express_name']     = $body['express']['express_name'] ?? '';
            $orderExtendsData['express_mobile']   = $body['express']['express_mobile'] ?? '';
            if( $order_type == CashOrderVolidate::BONDED_ORDER_TYPE )
            {
                $orderExtendsData['express_mobile']   = $body['express']['express_mobile'];
                $orderExtendsData['express_type']     = $body['express_type'];
                $orderExtendsData['express_name']     = $body['express']['express_name'];
                $orderExtendsData['express_province'] = $body['express']['express_province'];
                $orderExtendsData['express_city']     = $body['express']['express_city'];
                $orderExtendsData['express_area']     = $body['express']['express_area'];
                $orderExtendsData['express_address']  = $body['express']['express_address'];
                $addressdata = [
                    'true_name' => $body['express']['express_name'],
                    'mobile'    => $body['express']['express_mobile'],
                    'province'  => $body['express']['express_province'],
                    'city'      => $body['express']['express_city'],
                    'area'      => $body['express']['express_area'],
                    'address'   => $body['express']['express_address']
                ];
                if ($mid && $body['express_type'] == 2) {
                    $addressdatawhere = array_merge($addressdata, ['mid' => $mid]);
                    $addressres       = Address::instance()->info($addressdatawhere);
                } elseif ($mid && $body['express_type'] == 1) {
                    $addressflag = true;
                    if ($addressdata['true_name'] != $body['buyer']['truename'] ||
                        $addressdata['mobile'] != $body['buyer']['mobile'] ||
                        $addressdata['province'] != $mn_user['province'] ||
                        $addressdata['city'] != $mn_user['city'] ||
                        $addressdata['area'] != $mn_user['area'] ||
                        $addressdata['address'] != $mn_user['address']
                    ) {
                        $addressflag = false;
                    }
                }
            }

            //写订单数据
            $order_insert_id = Order::instance()->add($orderAddData);


            if($use_points > 0){
                $goods_points_res = GoodsPointsService::instance()->deductGoodsPoints($cid, $mid, $mn_sid, $use_points, $order_sn, "积分抵现(订单号:{$order_sn})");
                if( $goods_points_res['code'] != Normal::SUC ) {
                    return $goods_points_res;
                }
            }

            //分拥
            $commissionflag     = false;
            //剩余分减扣除
            $surplusonlinepay   = $scan_rece;
            //支付比例
            $pay_percent        = 0;

            //支付扫码
            if( $surplusonlinepay )
            {
                $pay_total = $body['pay_total'];
                if( $pay_total <= 0 ) {
                    return Normal::returnCode(Normal::FAIL,'订单支付总金额不能小于0');
                }

                $scan_rece = $orderExtendsData['scan_rece'];


                $commissionflag = true;
                $pay_percent = round(bcdiv((string)$scan_rece, (string)$pay_total, 3),2);//在线支付占比

            }

            //店铺收款，所有不分佣
            $commissionflag = false;
            //收银机专用附属信息表
            $orderExtendsData['order_id'] = $order_insert_id;
            $ordercountwhere = [
                ['cd', '>', strtotime(date('Y-m-d'))],
//                ['type', '=', $order_type],
                ['mn_sid', '=', $mn_sid],
                ['id', '<=', $order_insert_id]
            ];
            $LOCK_KEY = 'LOCK_STORE_SERIAL_NUMBER_' . $mn_sid;
            $SERIAL_NUMBER_KEY = 'STORE_SERIAL_NUMBER_CACHE' . $mn_sid . date('Y-m-d');
            $CacheExpire_time = 3600 * 24;
            $isLock = false;
            while (!$isLock) {
                $isLock=redis()->set($LOCK_KEY,1,['NX','EX'=>5]);
                if($isLock){
                    $storeSerialNumber=redis()->get($SERIAL_NUMBER_KEY);
                    if($storeSerialNumber){
                        redis()->incr($SERIAL_NUMBER_KEY);
                    }else{
                        $historycount=Order::instance()->where($ordercountwhere)->whereIn('type',[3,4])->count();
                        $storeSerialNumber=$historycount;
                        $countnum=$historycount+1;
                        redis()->set($SERIAL_NUMBER_KEY,$countnum,$CacheExpire_time);
                    }
                    redis()->del($LOCK_KEY);
                }else{
                    usleep(500000);
                }
            }
            if(isset($storeSerialNumber)&&$storeSerialNumber>0){
                $serial_number = $storeSerialNumber;
            }else{
                $orcercount    = Order::instance()->where($ordercountwhere)->whereIn('type',[3,4])->count();
                $serial_number = $orcercount;
            }
            $orderExtendsData['serial_number'] = str_pad((string)$serial_number, 4, '0', STR_PAD_LEFT);
            $order_extends_id = OrderExtends::instance()->add($orderExtendsData);
            if( !$order_extends_id ) {
                return Normal::returnCode(Normal::FAIL, '订单扩展新增失败');
            }

            //储值卡积分
            if( $points > 0 ) {
                $result_user_points = PointsService::instance()->deductUserPoints($cid, $mid, $mn_sid, $points,[
                    'order_id'          => $order_insert_id,
                    'order_extends_id'  => $order_extends_id
                ]);
                if( $result_user_points['code'] != Normal::SUC ) {
                    return $result_user_points;
                }
            }


            //订单商品处理
            $stock_extra = [
                'order_sn'              => $order_sn,
                'cid'                   => $cid,
                'mn_sid'                => $mn_sid,
                'order_id'              => $order_insert_id,
                'order_extends_id'      => $order_extends_id,
                'stock_share'           => $mn_user['stock_share'],
                'bill_id'               => isset($body['bill_id']) ? $body['bill_id'] : '',
                'bill_code'             => isset($body['bill_code']) ? $body['bill_code'] : '',
                'time'                  => $time,
                'manager_id'            => $manager_id,
                'goodsListMap'          => $body['goodsListMap'],
                'mnGoodsBatchListMap'   => $body['mnGoodsBatchListMap'],
                'mnGoodsListMap'        => $body['mnGoodsListMap'],
                'price_order'           => $body['price_order'],
                'goodsSaleListMap'      => $body['goodsSaleListMap'],
                'commissionflag'        => $commissionflag,
                'pay_fee'               => $pay_fee,
                'pay_percent'           => $pay_percent,
                'surplusonlinepay'      => $surplusonlinepay,
                'mn_user'               => $mn_user,
                'mid'                   => $mid,
            ];

            //扣除库存并且，组装订单商品数据
            $result_stock = $this->dealOrderGoods($orderAttr,$stock_extra,$storeProfitType,$orderAddData);
            if( $result_stock['code'] != Normal::SUC ) {
                return $result_stock;
            }
            $result_stock_data      = $result_stock['data'];
            $orderGoodsInsertData   = $result_stock_data['orderGoodsInsertData'];
            $yunCangOrderGoods      = $result_stock_data['yunCangOrderGoods'];
            $mnCommissionData       = $result_stock_data['mnCommissionData'];
            $ycgoodsprice           = $result_stock_data['yc_goods_price'];
            $order_profit           = $result_stock_data['order_profit'];
            $distribute_money       = $result_stock_data['distribute_money'];
            $total_commission       = $result_stock_data['total_commission'];
            $result_goods_insert = OrderGoods::instance()->insert($orderGoodsInsertData);
            if( !$result_goods_insert ) {
                return Normal::returnCode(Normal::FAIL, '订单商品信息新增失败');
            }

            $result_commission_insert = MnCommission::instance()->insert($mnCommissionData);
            if( !$result_commission_insert ) {
                return Normal::returnCode(Normal::FAIL, '订单商品分佣信息新增失败');
            }

            $ordercommission = [];

            //订单总分销金额,代发订单扣除了成本，自建商品订单为整单金额*0.994
            if( $distribute_money > 0 ){
                $ordercommission['distribute_money'] = $distribute_money;
            }

            //订单利润，用于计算导流分佣，代发订单时等于distribute_money,自建商品为订单金额减去加权成本价
            if($order_profit != 0 ) {
                $ordercommission['profit']  = $order_profit;
            }

            if($ordercommission){
                $ordereditres = Order::instance()->edit(['id'=> $order_insert_id], $ordercommission);
                if(!$ordereditres){
                    return Normal::returnCode(Normal::FAIL, '订单佣金修改失败');
                }
            }

            if($total_commission>0 && $commissionflag){
                $mnuserres= Mnuser::instance()->where(['id'=>$mn_sid])->increment('frozen_income',$total_commission);
                if(!$mnuserres){
                    return Normal::returnCode(Normal::FAIL, '用户待结算佣金修改失败');
                }
            }

            $mnuserres2 = Mnuser::instance()->where(['id'=>$mn_sid])->increment('all_sell',$body['price_order']);
            if(!$mnuserres2){
                return Normal::returnCode(Normal::FAIL, '用户待结算佣金修改失败2');
            }


            //保税订单需要进行支付单申报
            if( $order_type == CashOrderVolidate::BONDED_ORDER_TYPE ) {
                $order_report_status_data['order_id'] = $order_insert_id;
                $order_report_id = OrderReportStatus::instance()->add($order_report_status_data);
                if(!$order_report_id){
                    return Normal::returnCode(Normal::FAIL, '保税订单申报状态新增失败');
                }

                if($mid && $body['express_type']==2){
                    if(empty($addressres)){
                        $addressdatawhere['cd']=$time;
                        Address::instance()->add($addressdatawhere);
                    }
                    MemberInfo::instance()->edit(['mid'=>$mid], ['md'=>time(),'store_express_address'=>json_encode($addressdata,JSON_UNESCAPED_UNICODE)]);
                }elseif($mid && $body['express_type']==1 && $addressflag==false){
                    MemberInfo::instance()->edit(['mid'=>$mid], ['md'=>time(),'store_self_address'=>json_encode($addressdata,JSON_UNESCAPED_UNICODE)]);
                }
            }
            //非保税下单返积分
            if($order_type != CashOrderVolidate::BONDED_ORDER_TYPE && $mid>0){
                $memberinfo= Member::instance()->info(['mid'=>$mid]);
                if($return_goods_points>0){
                    $goodsPointsRes = GoodsPointsService::instance()->addGoodsPoints($cid, $mid, $mn_sid, $return_goods_points, $order_sn, "购物返积分(订单号:{$order_sn})");
                    if($goodsPointsRes['code']==Normal::FAIL){
                        return $goodsPointsRes;
                    }
                }
                if($return_parent_points>0&&$memberinfo['parent_id']>0){
                    $goodsparentPointsRes= GoodsPointsService::instance()->addGoodsPoints($cid, $memberinfo['parent_id'], $mn_sid, $return_parent_points, $order_sn, "下级购物返积分(订单号:{$order_sn})");
                    if($goodsparentPointsRes['code']==Normal::FAIL){
                        return $goodsparentPointsRes;
                    }
                }
            }


            //申报运单
            if( $order_type == CashOrderVolidate::BONDED_ORDER_TYPE )
            {


                $way_bill_data = [
                    'cid'               => $cid,
                    'mn_sid'            => $mn_sid,
                    'order_id'          => $order_insert_id,
                    'order_sn'          => $order_sn,
                    'order_report_id'   => $order_report_id,
                    'time'              => $time
                ];

                //云仓创建订单接口数据
                $pushYunCangCreateOrderData = [
                    'orderSn'           => $order_sn,
                    'buyerPhone'        => isset($body['buyer']['mobile'])?$body['buyer']['mobile']:'',
                    'buyerRealName'     => isset($body['buyer']['truename'])?$body['buyer']['truename']:'',
                    'buyerIdCard'       => isset($body['buyer']['idcard'])?$body['buyer']['idcard']:'',
                    'receiveAddress'    => isset($body['address'])?$body['address']['address']:'',
                    'receiveName'       => isset($body['address'])?$body['address']['true_name']:'',
                    'recveivePhone'     => isset($body['address'])?$body['address']['mobile']:'',
                    'province'          => isset($body['address'])?$body['address']['province']['name']:'',
                    'city'              => isset($body['address'])?$body['address']['city']['name']:'',
                    'district'          => isset($body['address'])?$body['address']['area']['name']:'',
                    'orderRemarks'      => isset($body['order_message'])?$body['order_message']:'',
                    'orderSource'       => $mn_user['store_name'].'收银',
                    'freight'           => 0,
                    'freightTax'        => 0,
                    'orderMoney'        => bcsub((string)$price_order,(string)$goods_points,2),
                    'cid'               => $cid,
                    'isOpen'            => 1,
                    'isOrderDeclare'    => 0,
                    'isPayDeclare'      => 1,
                    'discountMoney'     => bcadd(bcsub($ycgoodsprice, (string)$price_order,2),(string)$goods_points,2), //总的优惠金额(包含抵扣积分)
                    'orderType'         => 9,
                    'goods'             => $yunCangOrderGoods
                ];
                $extra = [
                    'orderCreate'       => $pushYunCangCreateOrderData,
                    'order_sn'          => $order_sn,
                    'order_id'          => $order_insert_id,
                    'scan_rece_type'    => $scan_rece_type,
                    'time'              => $time,
                    'logisticReport'    => '',
                    'mid'               => $mid,
                    'user_pay_result'   => '',
                    'goodsListMap'      => $return_goods_points_pram['goodsListMap'],
                ];

                $pushData['way_bill_data'] = $way_bill_data;
                $pushData['extra'] = $extra;

                $pushYunCangOrderData[] = $pushData;

            }
        }

        $returnData = [
            'pay_sn'               => $pay_sn,
            'scan_rece_type'       => $scan_rece_type,
            'pushYunCangOrderData' => $pushYunCangOrderData,
            'is_combination_order' => $is_combination_order,
        ];

        return Normal::returnCode(Normal::SUC,'订单创建成功',$returnData);

    }

    //运单数据，云仓订单推送
    public function CashOrderVolidate($cid,$mn_sid,$pushData,$user_pay_result){
        //申报运单
        foreach ($pushData as $val)
        {
            $way_bill_data = $val['way_bill_data'];
            $logisticReport = WayBillDeclareService::instance()->wayBillDeclare($way_bill_data);

            $extra = $val['extra'];
            $extra['logisticReport'] = $logisticReport;
            $extra['user_pay_result'] = $user_pay_result;
            $this->pushYunCangOrder($cid,$mn_sid,$extra);

        }

    }

    public function combinationOrder($cid,$mn_sid,$manager_id,$casher_id,$body){


        $orderSnIds = Order::instance()
            ->where('mn_sid',$mn_sid)
            ->where('pay_sn',$body['pay_sn'])
            ->pluck('id')->toArray();

        $table = Order::instance()->getTable();
        $query = Order::instance()
            ->from("{$table} as o")
            ->leftJoin('ly_member as m','o.mid','=','m.mid')
            ->leftJoin('ly_member_info as mi','o.mid','=','mi.mid')
            ->leftJoin('ly_order_report_status as ors','o.id','=','ors.order_id')
            ->leftJoin('ly_order_extends as  oes','o.id','=','oes.order_id')
            ->where('o.df',0)
            ->where('o.mn_sid',$mn_sid)
            ->whereIn('o.id',$orderSnIds);

        $select = [
            'o.*',
            'm.account',
            'mi.nickname',
            'ors.clear_status',
            'ors.clear_time',
            'ors.express_status',
            'ors.express_time',
            'ors.pay_report_status',
            'ors.pay_report_time',
            'ors.delivery_status',
            'ors.delivery_time',
            'ors.express_type',
            'ors.express_report_data',
            'ors.express_code',
            'ors.express_name',
            'm.vip_level',
            'm.vip_expired',
            'o.guide_id',
        ];

        //type排个序，报税在数组前面为了获取收货人地址联系方式数据
        $list       = $query->select($select)->orderByRaw('o.type desc,o.id asc')->get()->toArray();
        $orderIds   = array_column($list, 'id');

        //扩展
        $orderExtendsList = OrderService::instance()->queryOrderExtendsByIds($orderIds);
        $orderExtendsListMap = array_column($orderExtendsList,null,'order_id');


        //收银机
        $cashregister_ids       = array_column($orderExtendsList,'cashregister_id');
        $casherRegisterList     = CashManagerService::instance()->getCashRegisterByIds($cashregister_ids);
        $casherRegisterListMap  = array_column($casherRegisterList,null,'id');


        //收银员
        $casher_ids         = array_column($orderExtendsList,'casher');
        $casherList         = CashManagerService::instance()->getCasherByIds($casher_ids);
        $casherListMap      = array_column($casherList,null,'id');

        //获取下单商品数据
        $orderGoodsList     = OrderService::instance()->queryOrderGoodsByOrderIds($orderIds);
        $goodsIds           = array_column($orderGoodsList,'goods_id');
        $orderGoodsListMap  = getArrayGroupData($orderGoodsList,'order_id');

        //查询原始商品信息
        $goodsList          = ChannelGoodsService::instance()->queryGoodsList($goodsIds);
        $goodsListMap       = array_column($goodsList,null,'id');

        //储值卡信息
        $store_card_ids     = array_column($orderExtendsList,'storecard_id');
        $storeCardList      = StoreCardService::instance()->queryStoredCardByIds($store_card_ids);
        $storeCardListMap   = array_column($storeCardList,null,'id');

        //退款订单
        $orderSns = array_column($list,'sn');
        $orderRefundList = OrderService::instance()->queryOrderRefundBySns($orderSns);
        $orderRefundListMap = array_column($orderRefundList,null,'sn');

        $provinceIds        = array_column($orderExtendsList,'express_province');
        $cityIds            = array_column($orderExtendsList,'express_city');
        $areaIds            = array_column($orderExtendsList,'express_area');
        $allAreaIds         = array_merge($provinceIds,$cityIds,$areaIds);
        $areaListMap        = AreaService::instance()->queryAreaListById($allAreaIds);

        //申报日志
        $reportLog      = ReportLogService::instance()->getLogByOrderIds($orderIds);

        //供应商
        $supply_lists   = YunCangSupplier::instance()
            ->where(['cid' => $cid])
            ->where('supplier_name','<>','')
            ->get()->toArray();
        $supply_lists_map = array_column($supply_lists,null,'id');

        $data = [];
        foreach ($list as $key => $value)
        {
            $order_id = $value['id'];
            $order_sn = $value['sn'];
            $orderextends = $orderExtendsListMap[$order_id] ?? [];
            if( isset($orderextends['cashregister_id']) )
            {
                $cashregister   = $casherRegisterListMap[$orderextends['cashregister_id']] ?? [];
                $casher         = $casherListMap[$orderextends['casher']] ?? [] ;
                $storecardinfo  = $storeCardListMap[$orderextends['storecard_id']] ?? [] ;
            }

            $orderGoodsList = $orderGoodsListMap[$order_id];
            foreach ($orderGoodsList as & $goods)
            {
                $goods['barcode'] = $goodsListMap[$goods['goods_id']]['barcode'] ?? '未定义';
                $goods['skucode'] = $goodsListMap[$goods['goods_id']]['skucode'] ?? '未定义';

                /*                $goods['price']     = $goods['price'] / $goods['num'];
                                $goods['price_vip'] = $goods['price_vip'] / $goods['num'];*/
                if($goods['is_combine_goods'] == 1){ //组合商品
                    $single_goods              = $goods;
                    $single_goods['price_pay'] = $goods['price']; //普通用户单价

                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods, 1);
                    $price_tax                 = $combine_goods['price_total_tax'];//销售税金
                    $price                     = $goods['price'] - $price_tax;
                    $real_price_pay_tax        = $price_tax;

                    $single_goods['price_pay'] = $goods['price_vip']; //会员用户单价
                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods);
                    $price_vip_tax             = $combine_goods['price_total_tax'];//销售税金
                    $price_vip                 = $goods['price_vip'] - $price_vip_tax;

                }else{
                    if($goods['tax_rate']==0){
                        $goods['tax_rate']=$goodsListMap[$goods['goods_id']]['tax_rate'];
                    }
                    $taxflag            = bcadd('1', (string)$goods['tax_rate'],3);
                    $price              = bcdiv((string)$goods['price'], (string)$taxflag, 3);
                    $price_vip          = bcdiv((string)$goods['price_vip'], (string)$taxflag, 3);
                    $price              = number_format((float)$price,2,'.','');
                    $price_vip          = number_format((float)$price_vip,2,'.','');
                    $price_tax          = bcsub((string)$goods['price'], (string)$price,2);
                    $price_vip_tax      = bcsub((string)$goods['price_vip'], (string)$price_vip,2);

                    //真实销售税费
                    $real_price_pay_tax = (new CashGoodsService())->singGoodsPriceFree($goods['price'],$goods);

                }

                $goods['real_price_pay_tax'] = $real_price_pay_tax ?? 0;
                $goods['old_price_tax']      = $price_tax;
                $goods['old_price_vip_tax']  = $price_vip_tax;
                $goods['old_price']          = $price;
                $goods['old_price_vip']      = $price_vip;
                $goods['supplier_name']      = $supply_lists_map[$goods['supplier_id']]['supplier_name'] ?? '';


                $goods['price_tax']    = round($goods['price_tax'] / $goods['num'], 2);
            }
            if($value['vip_level']==1 && $value['vip_expired']>time()){
                $is_vip     =2;
                $vip_type   ="黑卡会员";
            }elseif($value['vip_level']==2 && $value['vip_expired']>time()){
                $is_vip     =2;
                $vip_type   ="高级会员";
            }elseif($value['account']){
                $is_vip     =1;
                $vip_type   ="普通会员";
            }else{
                $is_vip     =0;
                $vip_type   ="-";
            }

            //导购员
            $guide_name = ShoppingGuide::instance()
                ->where(['id' => $value['guide_id']])
                ->value('name');
            $data[] = [
                'id'                   => $value['id'],
                'cd'                   => $value['cd'],
                'sn'                   => $value['sn'],
                'status'               => $value['status'],
                'pay_sn'               => $value['pay_sn'],
                'pay_serial'           => $value['pay_serial'],
                'pay_time'             => $value['pay_time'] ? date('Y-m-d H:i:s', $value['pay_time']) : '',
                'account'              => $value['account'],
                'vip_level'            => $vip_type,
                'nickname'             => $value['nickname'],
                'return'               => empty($orderRefundListMap[$order_sn]) ? 0 : 1,
                'price_total'          => $value['price_total'],
                'price_order'          => $value['price_order'],
                'goods_num'            => $value['goods_num'],
                'order_message'        => $value['order_message'],
                'giveup_money'         => $orderextends['giveup_money'],
                'pay_way'              => explode(',', $orderextends['pay_way']),
                'cash'                 => $orderextends['cash'],
                'scan_pay'             => $orderextends['scan_pay'],
                'scan_rece'            => $orderextends['scan_rece'],
                'pos'                  => $orderextends['pos'],
                'storecard'            => $orderextends['storecard'],
                'storecard_num'        => $orderextends['storecard_id'] ? $storecardinfo['number'] : '',
                'storecard_id'         => $orderextends['storecard_id'],
                'balance'              => $orderextends['balance'],
                'coupon'               => $orderextends['coupon'],
                'goods_points'         => $orderextends['goods_points'],
                'price_coupon'         => $value['price_coupon'],
                'points'               => $orderextends['points'],
                'cashregister'         => $cashregister['name'] ?? '',
                'casher_id'            => $orderextends['casher'],
                'casher'               => $casher['name'] ?? '',
                'goods'                => $orderGoodsList,
                'tax_fee'              => $value['tax_fee'],
                'cash_receive'         => $orderextends['cash_receive'] ?? 0,
                'cash_reback'          => $orderextends['cash_reback'] ?? 0,
                'total_vipDiscount'    => $value['total_vipDiscount'],
                'total_fullReduction'  => $value['total_fullReduction'],
                'total_goodsReduction' => $value['total_goodsReduction'],
                'total_priceSpecial'   => $value['total_priceSpecial'],
                'total_discount'       => $value['total_discount'],
                'total_orderActivity'  => $value['total_orderActivity'],
                'total_modifyDiscount' => $value['total_modifyDiscount'],
                'express_num'          => $value['express_num'],
                'mobile'               => $value['buyer_mobile'],
                'buyer_mobile'         => $value['buyer_mobile'],
                'buyer_name'           => $value['buyer_name'],
                'buyer_idcard'         => StringService::hide_idcard($value['buyer_idcard']),
                'express_type'         => $orderextends['express_type'],
                'express_province'     => $orderextends['express_province'] ? $areaListMap[$orderextends['express_province']]['name'] : '',
                'express_city'         => $orderextends['express_city'] ? $areaListMap[$orderextends['express_city']]['name'] : '',
                'express_area'         => $orderextends['express_area'] ? $areaListMap[$orderextends['express_area']]['name'] : '',
                'express_address'      => $orderextends['express_address'],
                'express_name'         => $orderextends['express_name'],
                'express_mobile'       => $orderextends['express_mobile'],
                'serial_number'        => str_pad((string)$orderextends['serial_number'], 4, '0', STR_PAD_LEFT),
                'user_pay_type'        => $orderextends['user_pay_type'] ? OrderService::instance()->user_pay_type[$orderextends['user_pay_type']] : '',
                'clear_status'         => $value['clear_status'],
                'clear_time'           => $value['clear_time'] ? date('Y-m-d H:i:s', $value['clear_time']) : '',
                'express_status'       => $value['express_status'],
                'express_time'         => $value['express_time'] ? date('Y-m-d H:i:s', $value['express_time']) : '',
                'pay_report_status'    => $value['pay_report_status'],
                'pay_report_time'      => $value['pay_report_time'] ? date('Y-m-d H:i:s', $value['pay_report_time']) : '',
                'order_report_status'  => $value['clear_status'] == 2 ? 1 : $value['clear_status'],
                'order_report_time'    => $value['clear_time'] ? date('Y-m-d H:i:s', $value['clear_time']) : '',
                'delivery_status'      => $value['delivery_status'],
                'delivery_time'        => $value['delivery_status'] ? date('Y-m-d H:i:s', $value['delivery_status']) : '',
                'reportlog'            => $reportLog[$value['id']] ?? [],
                'express_report_code'  => $value['express_code'],
                'express_report_name'  => $value['express_name'],
                'express_report_type'  => $value['express_type'],
                'express_report_data'  => $value['express_report_data'],
                'guide_name'           => $guide_name,
            ];
        }

        $returnData = [];
        //组装主订单数据
        if($data){

            $returnData = $data[0];
            foreach ($data as $key => $value) {

                foreach ($value['goods'] as $v){
                    $orderGoodsData[] = $v;
                }
            }

            $returnData['cash']                 = array_sum(array_column($data, 'cash'));
            $returnData['scan_pay']             = array_sum(array_column($data, 'scan_pay'));
            $returnData['scan_rece']            = array_sum(array_column($data, 'scan_rece'));
            $returnData['storecard']            = array_sum(array_column($data, 'storecard'));
            $returnData['coupon']               = array_sum(array_column($data, 'coupon'));
            $returnData['goods_points']         = array_sum(array_column($data, 'goods_points'));
            $returnData['price_coupon']         = array_sum(array_column($data, 'price_coupon'));
            $returnData['points']               = array_sum(array_column($data, 'points'));
            $returnData['tax_fee']              = array_sum(array_column($data, 'tax_fee'));
            $returnData['total_vipDiscount']    = array_sum(array_column($data, 'total_vipDiscount'));
            $returnData['total_fullReduction']  = array_sum(array_column($data, 'total_fullReduction'));
            $returnData['total_goodsReduction'] = array_sum(array_column($data, 'total_goodsReduction'));
            $returnData['total_priceSpecial']   = array_sum(array_column($data, 'total_priceSpecial'));
            $returnData['total_discount']       = array_sum(array_column($data, 'total_discount'));
            $returnData['total_orderActivity']  = array_sum(array_column($data, 'total_orderActivity'));
            $returnData['total_modifyDiscount'] = array_sum(array_column($data, 'total_modifyDiscount'));
            $returnData['price_total']          = array_sum(array_column($data,'price_total'));
            $returnData['price_order']          = array_sum(array_column($data,'price_order'));

            $returnData['goods'] = $orderGoodsData;
        }

        return Normal::returnCode(Normal::SUC, '成功',$returnData);
    }

}
